1 /*
2 * fs.c - NTFS driver for Linux 2.4.x
3 *
4 * Legato Systems, Inc. (http://www.legato.com) have sponsored Anton
5 * Altaparmakov to develop NTFS on Linux since June 2001.
6 *
7 * Copyright (C) 1995-1997, 1999 Martin von L�wis
8 * Copyright (C) 1996 Richard Russon
9 * Copyright (C) 1996-1997 R�gis Duchesne
10 * Copyright (C) 2000-2001, Anton Altaparmakov (AIA)
11 */
12
13 #include <linux/config.h>
14 #include <linux/errno.h>
15 #include "ntfstypes.h"
16 #include "struct.h"
17 #include "util.h"
18 #include "inode.h"
19 #include "super.h"
20 #include "dir.h"
21 #include "support.h"
22 #include "macros.h"
23 #include "sysctl.h"
24 #include "attr.h"
25 #include <linux/module.h>
26 #include <asm/uaccess.h>
27 #include <linux/locks.h>
28 #include <linux/init.h>
29 #include <linux/smp_lock.h>
30 #include <linux/blkdev.h>
31 #include <asm/page.h>
32 #include <linux/nls.h>
33 #include <linux/ntfs_fs.h>
34
35 /* Forward declarations. */
36 static struct inode_operations ntfs_dir_inode_operations;
37 static struct file_operations ntfs_dir_operations;
38
39 #define ITEM_SIZE 2040
40
41 /* Io functions to user space. */
ntfs_putuser(ntfs_io * dest,void * src,ntfs_size_t len)42 static void ntfs_putuser(ntfs_io* dest, void *src, ntfs_size_t len)
43 {
44 copy_to_user(dest->param, src, len);
45 dest->param += len;
46 }
47
48 #ifdef CONFIG_NTFS_RW
49 struct ntfs_getuser_update_vm_s {
50 const char *user;
51 struct inode *ino;
52 loff_t off;
53 };
54
ntfs_getuser_update_vm(void * dest,ntfs_io * src,ntfs_size_t len)55 static void ntfs_getuser_update_vm(void *dest, ntfs_io *src, ntfs_size_t len)
56 {
57 struct ntfs_getuser_update_vm_s *p = src->param;
58
59 copy_from_user(dest, p->user, len);
60 p->user += len;
61 p->off += len;
62 }
63 #endif
64
65 /* loff_t is 64 bit signed, so is cool. */
ntfs_read(struct file * filp,char * buf,size_t count,loff_t * off)66 static ssize_t ntfs_read(struct file *filp, char *buf, size_t count,loff_t *off)
67 {
68 int error;
69 ntfs_io io;
70 ntfs_attribute *attr;
71 ntfs_inode *ino = NTFS_LINO2NINO(filp->f_dentry->d_inode);
72
73 /* Inode is not properly initialized. */
74 if (!ino)
75 return -EINVAL;
76 ntfs_debug(DEBUG_OTHER, "ntfs_read %x, %Lx, %x ->",
77 (unsigned)ino->i_number, (unsigned long long)*off,
78 (unsigned)count);
79 attr = ntfs_find_attr(ino, ino->vol->at_data, NULL);
80 /* Inode has no unnamed data attribute. */
81 if (!attr) {
82 ntfs_debug(DEBUG_OTHER, "ntfs_read: $DATA not found!\n");
83 return -EINVAL;
84 }
85 if (attr->flags & ATTR_IS_ENCRYPTED)
86 return -EACCES;
87 /* Read the data. */
88 io.fn_put = ntfs_putuser;
89 io.fn_get = 0;
90 io.param = buf;
91 io.size = count;
92 error = ntfs_read_attr(ino, ino->vol->at_data, NULL, *off, &io);
93 if (error && !io.size) {
94 ntfs_debug(DEBUG_OTHER, "ntfs_read: read_attr failed with "
95 "error %i, io size %u.\n", error, io.size);
96 return error;
97 }
98 *off += io.size;
99 ntfs_debug(DEBUG_OTHER, "ntfs_read: finished. read %u bytes.\n",
100 io.size);
101 return io.size;
102 }
103
104 #ifdef CONFIG_NTFS_RW
ntfs_write(struct file * filp,const char * buf,size_t count,loff_t * pos)105 static ssize_t ntfs_write(struct file *filp, const char *buf, size_t count,
106 loff_t *pos)
107 {
108 int err;
109 struct inode *vfs_ino = filp->f_dentry->d_inode;
110 ntfs_inode *ntfs_ino = NTFS_LINO2NINO(vfs_ino);
111 ntfs_attribute *data;
112 ntfs_io io;
113 struct ntfs_getuser_update_vm_s param;
114
115 if (!ntfs_ino)
116 return -EINVAL;
117 ntfs_debug(DEBUG_LINUX, "%s(): Entering for inode 0x%lx, *pos 0x%Lx, "
118 "count 0x%x.\n", __FUNCTION__, ntfs_ino->i_number,
119 *pos, count);
120 /* Allows to lock fs ro at any time. */
121 if (vfs_ino->i_sb->s_flags & MS_RDONLY)
122 return -EROFS;
123 data = ntfs_find_attr(ntfs_ino, ntfs_ino->vol->at_data, NULL);
124 if (!data)
125 return -EINVAL;
126 /* Evaluating O_APPEND is the file system's job... */
127 if (filp->f_flags & O_APPEND)
128 *pos = vfs_ino->i_size;
129 if (!data->resident && *pos + count > data->allocated) {
130 err = ntfs_extend_attr(ntfs_ino, data, *pos + count);
131 if (err < 0)
132 return err;
133 }
134 param.user = buf;
135 param.ino = vfs_ino;
136 param.off = *pos;
137 io.fn_put = 0;
138 io.fn_get = ntfs_getuser_update_vm;
139 io.param = ¶m;
140 io.size = count;
141 io.do_read = 0;
142 err = ntfs_readwrite_attr(ntfs_ino, data, *pos, &io);
143 ntfs_debug(DEBUG_LINUX, "%s(): Returning %i\n", __FUNCTION__, -err);
144 if (!err) {
145 *pos += io.size;
146 if (*pos > vfs_ino->i_size)
147 vfs_ino->i_size = *pos;
148 mark_inode_dirty(vfs_ino);
149 return io.size;
150 }
151 return err;
152 }
153 #endif
154
155 struct ntfs_filldir {
156 struct inode *dir;
157 filldir_t filldir;
158 unsigned int type;
159 u32 ph, pl;
160 void *dirent;
161 char *name;
162 int namelen;
163 int ret_code;
164 };
165
ntfs_printcb(ntfs_u8 * entry,void * param)166 static int ntfs_printcb(ntfs_u8 *entry, void *param)
167 {
168 unsigned long inum = NTFS_GETU64(entry) & 0xffffffffffff;
169 struct ntfs_filldir *nf = param;
170 u32 flags = NTFS_GETU32(entry + 0x48);
171 char show_sys_files = 0;
172 u8 name_len = NTFS_GETU8(entry + 0x50);
173 u8 name_type = NTFS_GETU8(entry + 0x51);
174 int err;
175 unsigned file_type;
176
177 switch (nf->type) {
178 case ngt_dos:
179 /* Don't display long names. */
180 if (!(name_type & 2))
181 return 0;
182 break;
183 case ngt_nt:
184 /* Don't display short-only names. */
185 if ((name_type & 3) == 2)
186 return 0;
187 break;
188 case ngt_posix:
189 break;
190 case ngt_full:
191 show_sys_files = 1;
192 break;
193 default:
194 BUG();
195 }
196 err = ntfs_encodeuni(NTFS_INO2VOL(nf->dir), (ntfs_u16*)(entry + 0x52),
197 name_len, &nf->name, &nf->namelen);
198 if (err) {
199 ntfs_debug(DEBUG_OTHER, "%s(): Skipping unrepresentable "
200 "file.\n", __FUNCTION__);
201 err = 0;
202 goto err_noname;
203 }
204 if (!show_sys_files && inum < 0x10UL) {
205 ntfs_debug(DEBUG_OTHER, "%s(): Skipping system file (%s).\n",
206 __FUNCTION__, nf->name);
207 err = 0;
208 goto err_ret;
209 }
210 /* Do not return ".", as this is faked. */
211 if (nf->namelen == 1 && nf->name[0] == '.') {
212 ntfs_debug(DEBUG_OTHER, "%s(): Skipping \".\"\n", __FUNCTION__);
213 err = 0;
214 goto err_ret;
215 }
216 nf->name[nf->namelen] = 0;
217 if (flags & 0x10000000) /* FILE_ATTR_DUP_FILE_NAME_INDEX_PRESENT */
218 file_type = DT_DIR;
219 else
220 file_type = DT_REG;
221 ntfs_debug(DEBUG_OTHER, "%s(): Calling filldir for %s with "
222 "len %i, f_pos 0x%Lx, inode %lu, %s.\n", __FUNCTION__,
223 nf->name, nf->namelen, (loff_t)(nf->ph << 16) | nf->pl,
224 inum, file_type == DT_DIR ? "DT_DIR" : "DT_REG");
225 /*
226 * Userspace side of filldir expects an off_t rather than an loff_t.
227 * And it also doesn't like the most significant bit being set as it
228 * then considers the value to be negative. Thus this implementation
229 * limits the number of index records to 32766, which should be plenty.
230 */
231 err = nf->filldir(nf->dirent, nf->name, nf->namelen,
232 (loff_t)(nf->ph << 16) | nf->pl, inum, file_type);
233 if (err)
234 nf->ret_code = err;
235 err_ret:
236 ntfs_free(nf->name);
237 err_noname:
238 nf->namelen = 0;
239 nf->name = NULL;
240 return err;
241 }
242
243 /*
244 * readdir returns '.', then '..', then the directory entries in sequence.
245 * As the root directory contains an entry for itself, '.' is not emulated for
246 * the root directory.
247 */
ntfs_readdir(struct file * filp,void * dirent,filldir_t filldir)248 static int ntfs_readdir(struct file* filp, void *dirent, filldir_t filldir)
249 {
250 struct inode *dir = filp->f_dentry->d_inode;
251 int err;
252 struct ntfs_filldir cb;
253
254 cb.ret_code = 0;
255 cb.pl = filp->f_pos & 0xffff;
256 cb.ph = (filp->f_pos >> 16) & 0x7fff;
257 filp->f_pos = (loff_t)(cb.ph << 16) | cb.pl;
258 ntfs_debug(DEBUG_OTHER, "%s(): Entering for inode %lu, f_pos 0x%Lx, "
259 "i_mode 0x%x, i_count %lu.\n", __FUNCTION__,
260 dir->i_ino, filp->f_pos, (unsigned int)dir->i_mode,
261 atomic_read(&dir->i_count));
262 if (!cb.ph) {
263 /* Start of directory. Emulate "." and "..". */
264 if (!cb.pl) {
265 ntfs_debug(DEBUG_OTHER, "%s(): Calling filldir for . "
266 "with len 1, f_pos 0x%Lx, inode %lu, "
267 "DT_DIR.\n", __FUNCTION__, filp->f_pos,
268 dir->i_ino);
269 cb.ret_code = filldir(dirent, ".", 1, filp->f_pos,
270 dir->i_ino, DT_DIR);
271 if (cb.ret_code)
272 goto done;
273 cb.pl++;
274 filp->f_pos = (loff_t)(cb.ph << 16) | cb.pl;
275 }
276 if (cb.pl == (u32)1) {
277 ntfs_debug(DEBUG_OTHER, "%s(): Calling filldir for .. "
278 "with len 2, f_pos 0x%Lx, inode %lu, "
279 "DT_DIR.\n", __FUNCTION__, filp->f_pos,
280 filp->f_dentry->d_parent->d_inode->i_ino);
281 cb.ret_code = filldir(dirent, "..", 2, filp->f_pos,
282 filp->f_dentry->d_parent->d_inode->i_ino,
283 DT_DIR);
284 if (cb.ret_code)
285 goto done;
286 cb.pl++;
287 filp->f_pos = (loff_t)(cb.ph << 16) | cb.pl;
288 }
289 } else if (cb.ph >= 0x7fff)
290 /* End of directory. */
291 goto done;
292 cb.dir = dir;
293 cb.filldir = filldir;
294 cb.dirent = dirent;
295 cb.type = NTFS_INO2VOL(dir)->ngt;
296 do {
297 ntfs_debug(DEBUG_OTHER, "%s(): Looking for next file using "
298 "ntfs_getdir_unsorted(), f_pos 0x%Lx.\n",
299 __FUNCTION__, (loff_t)(cb.ph << 16) | cb.pl);
300 err = ntfs_getdir_unsorted(NTFS_LINO2NINO(dir), &cb.ph, &cb.pl,
301 ntfs_printcb, &cb);
302 } while (!err && !cb.ret_code && cb.ph < 0x7fff);
303 filp->f_pos = (loff_t)(cb.ph << 16) | cb.pl;
304 ntfs_debug(DEBUG_OTHER, "%s(): After ntfs_getdir_unsorted()"
305 " calls, f_pos 0x%Lx.\n", __FUNCTION__, filp->f_pos);
306 if (!err) {
307 done:
308 #ifdef DEBUG
309 if (!cb.ret_code)
310 ntfs_debug(DEBUG_OTHER, "%s(): EOD, f_pos 0x%Lx, "
311 "returning 0.\n", __FUNCTION__,
312 filp->f_pos);
313 else
314 ntfs_debug(DEBUG_OTHER, "%s(): filldir returned %i, "
315 "returning 0, f_pos 0x%Lx.\n",
316 __FUNCTION__, cb.ret_code, filp->f_pos);
317 #endif
318 return 0;
319 }
320 ntfs_debug(DEBUG_OTHER, "%s(): Returning %i, f_pos 0x%Lx.\n",
321 __FUNCTION__, err, filp->f_pos);
322 return err;
323 }
324
325 /* Copied from vfat driver. */
simple_getbool(char * s,int * setval)326 static int simple_getbool(char *s, int *setval)
327 {
328 if (s) {
329 if (!strcmp(s, "1") || !strcmp(s, "yes") || !strcmp(s, "true"))
330 *setval = 1;
331 else if (!strcmp(s, "0") || !strcmp(s, "no") ||
332 !strcmp(s, "false"))
333 *setval = 0;
334 else
335 return 0;
336 } else
337 *setval = 1;
338 return 1;
339 }
340
341 /*
342 * This needs to be outside parse_options() otherwise a remount will reset
343 * these unintentionally.
344 */
init_ntfs_super_block(ntfs_volume * vol)345 static void init_ntfs_super_block(ntfs_volume* vol)
346 {
347 vol->uid = vol->gid = 0;
348 vol->umask = 0077;
349 vol->ngt = ngt_nt;
350 vol->nls_map = (void*)-1;
351 vol->mft_zone_multiplier = -1;
352 }
353
354 /* Parse the (re)mount options. */
parse_options(ntfs_volume * vol,char * opt)355 static int parse_options(ntfs_volume *vol, char *opt)
356 {
357 char *value; /* Defaults if not specified and !remount. */
358 ntfs_uid_t uid = -1; /* 0, root user only */
359 ntfs_gid_t gid = -1; /* 0, root user only */
360 int umask = -1; /* 0077, owner access only */
361 unsigned int ngt = -1; /* ngt_nt */
362 void *nls_map = NULL; /* Try to load the default NLS. */
363 int use_utf8 = -1; /* If no NLS specified and loading the default
364 NLS failed use utf8. */
365 int mft_zone_mul = -1; /* 1 */
366
367 if (!opt)
368 goto done;
369 for (opt = strtok(opt, ","); opt; opt = strtok(NULL, ",")) {
370 if ((value = strchr(opt, '=')) != NULL)
371 *value ++= '\0';
372 if (strcmp(opt, "uid") == 0) {
373 if (!value || !*value)
374 goto needs_arg;
375 uid = simple_strtoul(value, &value, 0);
376 if (*value) {
377 printk(KERN_ERR "NTFS: uid invalid argument\n");
378 return 0;
379 }
380 } else if (strcmp(opt, "gid") == 0) {
381 if (!value || !*value)
382 goto needs_arg;
383 gid = simple_strtoul(value, &value, 0);
384 if (*value) {
385 printk(KERN_ERR "NTFS: gid invalid argument\n");
386 return 0;
387 }
388 } else if (strcmp(opt, "umask") == 0) {
389 if (!value || !*value)
390 goto needs_arg;
391 umask = simple_strtoul(value, &value, 0);
392 if (*value) {
393 printk(KERN_ERR "NTFS: umask invalid "
394 "argument\n");
395 return 0;
396 }
397 } else if (strcmp(opt, "mft_zone_multiplier") == 0) {
398 unsigned long ul;
399
400 if (!value || !*value)
401 goto needs_arg;
402 ul = simple_strtoul(value, &value, 0);
403 if (*value) {
404 printk(KERN_ERR "NTFS: mft_zone_multiplier "
405 "invalid argument\n");
406 return 0;
407 }
408 if (ul >= 1 && ul <= 4)
409 mft_zone_mul = ul;
410 else {
411 mft_zone_mul = 1;
412 printk(KERN_WARNING "NTFS: mft_zone_multiplier "
413 "out of range. Setting to 1.\n");
414 }
415 } else if (strcmp(opt, "posix") == 0) {
416 int val;
417 if (!value || !*value)
418 goto needs_arg;
419 if (!simple_getbool(value, &val))
420 goto needs_bool;
421 ngt = val ? ngt_posix : ngt_nt;
422 } else if (strcmp(opt, "show_sys_files") == 0) {
423 int val = 0;
424 if (!value || !*value)
425 val = 1;
426 else if (!simple_getbool(value, &val))
427 goto needs_bool;
428 ngt = val ? ngt_full : ngt_nt;
429 } else if (strcmp(opt, "iocharset") == 0) {
430 if (!value || !*value)
431 goto needs_arg;
432 nls_map = load_nls(value);
433 if (!nls_map) {
434 printk(KERN_ERR "NTFS: charset not found");
435 return 0;
436 }
437 } else if (strcmp(opt, "utf8") == 0) {
438 int val = 0;
439 if (!value || !*value)
440 val = 1;
441 else if (!simple_getbool(value, &val))
442 goto needs_bool;
443 use_utf8 = val;
444 } else {
445 printk(KERN_ERR "NTFS: unkown option '%s'\n", opt);
446 return 0;
447 }
448 }
449 done:
450 if (use_utf8 == -1) {
451 /* utf8 was not specified at all. */
452 if (!nls_map) {
453 /*
454 * No NLS was specified. If first mount, load the
455 * default NLS, otherwise don't change the NLS setting.
456 */
457 if (vol->nls_map == (void*)-1)
458 vol->nls_map = load_nls_default();
459 } else {
460 /* If an NLS was already loaded, unload it first. */
461 if (vol->nls_map && vol->nls_map != (void*)-1)
462 unload_nls(vol->nls_map);
463 /* Use the specified NLS. */
464 vol->nls_map = nls_map;
465 }
466 } else {
467 /* utf8 was specified. */
468 if (use_utf8 && nls_map) {
469 unload_nls(nls_map);
470 printk(KERN_ERR "NTFS: utf8 cannot be combined with "
471 "iocharset.\n");
472 return 0;
473 }
474 /* If an NLS was already loaded, unload it first. */
475 if (vol->nls_map && vol->nls_map != (void*)-1)
476 unload_nls(vol->nls_map);
477 if (!use_utf8) {
478 /* utf8 was specified as false. */
479 if (!nls_map)
480 /* No NLS was specified, load the default. */
481 vol->nls_map = load_nls_default();
482 else
483 /* Use the specified NLS. */
484 vol->nls_map = nls_map;
485 } else
486 /* utf8 was specified as true. */
487 vol->nls_map = NULL;
488 }
489 if (uid != -1)
490 vol->uid = uid;
491 if (gid != -1)
492 vol->gid = gid;
493 if (umask != -1)
494 vol->umask = (ntmode_t)umask;
495 if (ngt != -1)
496 vol->ngt = ngt;
497 if (mft_zone_mul != -1) {
498 /* mft_zone_multiplier was specified. */
499 if (vol->mft_zone_multiplier != -1) {
500 /* This is a remount, ignore a change and warn user. */
501 if (vol->mft_zone_multiplier != mft_zone_mul)
502 printk(KERN_WARNING "NTFS: Ignoring changes in "
503 "mft_zone_multiplier on "
504 "remount. If you want to "
505 "change this you need to "
506 "umount and mount again.\n");
507 } else
508 /* Use the specified multiplier. */
509 vol->mft_zone_multiplier = mft_zone_mul;
510 } else if (vol->mft_zone_multiplier == -1)
511 /* No multiplier specified and first mount, so set default. */
512 vol->mft_zone_multiplier = 1;
513 return 1;
514 needs_arg:
515 printk(KERN_ERR "NTFS: %s needs an argument", opt);
516 return 0;
517 needs_bool:
518 printk(KERN_ERR "NTFS: %s needs boolean argument", opt);
519 return 0;
520 }
521
ntfs_lookup(struct inode * dir,struct dentry * d)522 static struct dentry *ntfs_lookup(struct inode *dir, struct dentry *d)
523 {
524 struct inode *res = 0;
525 char *item = 0;
526 ntfs_iterate_s walk;
527 int err;
528
529 ntfs_debug(DEBUG_NAME1, "%s(): Looking up %s in directory ino 0x%x.\n",
530 __FUNCTION__, d->d_name.name, (unsigned)dir->i_ino);
531 walk.name = NULL;
532 walk.namelen = 0;
533 /* Convert to wide string. */
534 err = ntfs_decodeuni(NTFS_INO2VOL(dir), (char*)d->d_name.name,
535 d->d_name.len, &walk.name, &walk.namelen);
536 if (err)
537 goto err_ret;
538 item = ntfs_malloc(ITEM_SIZE);
539 if (!item) {
540 err = -ENOMEM;
541 goto err_ret;
542 }
543 /* ntfs_getdir will place the directory entry into item, and the first
544 * long long is the MFT record number. */
545 walk.type = BY_NAME;
546 walk.dir = NTFS_LINO2NINO(dir);
547 walk.result = item;
548 if (ntfs_getdir_byname(&walk))
549 res = iget(dir->i_sb, NTFS_GETU32(item));
550 d_add(d, res);
551 ntfs_free(item);
552 ntfs_free(walk.name);
553 /* Always return success, the dcache will handle negative entries. */
554 return NULL;
555 err_ret:
556 ntfs_free(walk.name);
557 return ERR_PTR(err);
558 }
559
560 static struct file_operations ntfs_file_operations = {
561 llseek: generic_file_llseek,
562 read: ntfs_read,
563 #ifdef CONFIG_NTFS_RW
564 write: ntfs_write,
565 #endif
566 open: generic_file_open,
567 };
568
569 static struct inode_operations ntfs_inode_operations;
570
571 #ifdef CONFIG_NTFS_RW
ntfs_create(struct inode * dir,struct dentry * d,int mode)572 static int ntfs_create(struct inode* dir, struct dentry *d, int mode)
573 {
574 struct inode *r = 0;
575 ntfs_inode *ino = 0;
576 ntfs_volume *vol;
577 int error = 0;
578 ntfs_attribute *si;
579
580 r = new_inode(dir->i_sb);
581 if (!r) {
582 error = -ENOMEM;
583 goto fail;
584 }
585 ntfs_debug(DEBUG_OTHER, "ntfs_create %s\n", d->d_name.name);
586 vol = NTFS_INO2VOL(dir);
587 ino = NTFS_LINO2NINO(r);
588 error = ntfs_alloc_file(NTFS_LINO2NINO(dir), ino, (char*)d->d_name.name,
589 d->d_name.len);
590 if (error) {
591 ntfs_error("ntfs_alloc_file FAILED: error = %i", error);
592 goto fail;
593 }
594 /* Not doing this one was causing a huge amount of corruption! Now the
595 * bugger bytes the dust! (-8 (AIA) */
596 r->i_ino = ino->i_number;
597 error = ntfs_update_inode(ino);
598 if (error)
599 goto fail;
600 error = ntfs_update_inode(NTFS_LINO2NINO(dir));
601 if (error)
602 goto fail;
603 r->i_uid = vol->uid;
604 r->i_gid = vol->gid;
605 /* FIXME: dirty? dev? */
606 /* Get the file modification times from the standard information. */
607 si = ntfs_find_attr(ino, vol->at_standard_information, NULL);
608 if (si) {
609 char *attr = si->d.data;
610 r->i_atime = ntfs_ntutc2unixutc(NTFS_GETU64(attr + 0x18));
611 r->i_ctime = ntfs_ntutc2unixutc(NTFS_GETU64(attr));
612 r->i_mtime = ntfs_ntutc2unixutc(NTFS_GETU64(attr + 8));
613 }
614 /* It's not a directory */
615 r->i_op = &ntfs_inode_operations;
616 r->i_fop = &ntfs_file_operations;
617 r->i_mode = S_IFREG | S_IRUGO;
618 #ifdef CONFIG_NTFS_RW
619 r->i_mode |= S_IWUGO;
620 #endif
621 r->i_mode &= ~vol->umask;
622 insert_inode_hash(r);
623 d_instantiate(d, r);
624 return 0;
625 fail:
626 if (r)
627 iput(r);
628 return error;
629 }
630
_linux_ntfs_mkdir(struct inode * dir,struct dentry * d,int mode)631 static int _linux_ntfs_mkdir(struct inode *dir, struct dentry* d, int mode)
632 {
633 int error;
634 struct inode *r = 0;
635 ntfs_volume *vol;
636 ntfs_inode *ino;
637 ntfs_attribute *si;
638
639 ntfs_debug (DEBUG_DIR1, "mkdir %s in %x\n", d->d_name.name, dir->i_ino);
640 error = -ENAMETOOLONG;
641 if (d->d_name.len > /* FIXME: */ 255)
642 goto out;
643 error = -EIO;
644 r = new_inode(dir->i_sb);
645 if (!r)
646 goto out;
647 vol = NTFS_INO2VOL(dir);
648 ino = NTFS_LINO2NINO(r);
649 error = ntfs_mkdir(NTFS_LINO2NINO(dir), d->d_name.name, d->d_name.len,
650 ino);
651 if (error)
652 goto out;
653 /* Not doing this one was causing a huge amount of corruption! Now the
654 * bugger bytes the dust! (-8 (AIA) */
655 r->i_ino = ino->i_number;
656 r->i_uid = vol->uid;
657 r->i_gid = vol->gid;
658 si = ntfs_find_attr(ino, vol->at_standard_information, NULL);
659 if (si) {
660 char *attr = si->d.data;
661 r->i_atime = ntfs_ntutc2unixutc(NTFS_GETU64(attr + 0x18));
662 r->i_ctime = ntfs_ntutc2unixutc(NTFS_GETU64(attr));
663 r->i_mtime = ntfs_ntutc2unixutc(NTFS_GETU64(attr + 8));
664 }
665 /* It's a directory. */
666 r->i_op = &ntfs_dir_inode_operations;
667 r->i_fop = &ntfs_dir_operations;
668 r->i_mode = S_IFDIR | S_IRUGO | S_IXUGO;
669 #ifdef CONFIG_NTFS_RW
670 r->i_mode |= S_IWUGO;
671 #endif
672 r->i_mode &= ~vol->umask;
673
674 insert_inode_hash(r);
675 d_instantiate(d, r);
676 error = 0;
677 out:
678 ntfs_debug (DEBUG_DIR1, "mkdir returns %d\n", error);
679 return error;
680 }
681 #endif
682
683 static struct file_operations ntfs_dir_operations = {
684 read: generic_read_dir,
685 readdir: ntfs_readdir,
686 };
687
688 static struct inode_operations ntfs_dir_inode_operations = {
689 lookup: ntfs_lookup,
690 #ifdef CONFIG_NTFS_RW
691 create: ntfs_create,
692 mkdir: _linux_ntfs_mkdir,
693 #endif
694 };
695
696 /* ntfs_read_inode() is called by the Virtual File System (the kernel layer
697 * that deals with filesystems) when iget is called requesting an inode not
698 * already present in the inode table. Typically filesystems have separate
699 * inode_operations for directories, files and symlinks. */
ntfs_read_inode(struct inode * inode)700 static void ntfs_read_inode(struct inode* inode)
701 {
702 ntfs_volume *vol;
703 ntfs_inode *ino;
704 ntfs_attribute *data;
705 ntfs_attribute *si;
706
707 vol = NTFS_INO2VOL(inode);
708 inode->i_mode = 0;
709 ntfs_debug(DEBUG_OTHER, "ntfs_read_inode 0x%lx\n", inode->i_ino);
710 switch (inode->i_ino) {
711 /* Those are loaded special files. */
712 case FILE_Mft:
713 if (!vol->mft_ino || ((vol->ino_flags & 1) == 0))
714 goto sys_file_error;
715 ntfs_memcpy(&inode->u.ntfs_i, vol->mft_ino, sizeof(ntfs_inode));
716 ino = vol->mft_ino;
717 vol->mft_ino = &inode->u.ntfs_i;
718 vol->ino_flags &= ~1;
719 ntfs_free(ino);
720 ino = vol->mft_ino;
721 ntfs_debug(DEBUG_OTHER, "Opening $MFT!\n");
722 break;
723 case FILE_MftMirr:
724 if (!vol->mftmirr || ((vol->ino_flags & 2) == 0))
725 goto sys_file_error;
726 ntfs_memcpy(&inode->u.ntfs_i, vol->mftmirr, sizeof(ntfs_inode));
727 ino = vol->mftmirr;
728 vol->mftmirr = &inode->u.ntfs_i;
729 vol->ino_flags &= ~2;
730 ntfs_free(ino);
731 ino = vol->mftmirr;
732 ntfs_debug(DEBUG_OTHER, "Opening $MFTMirr!\n");
733 break;
734 case FILE_BitMap:
735 if (!vol->bitmap || ((vol->ino_flags & 4) == 0))
736 goto sys_file_error;
737 ntfs_memcpy(&inode->u.ntfs_i, vol->bitmap, sizeof(ntfs_inode));
738 ino = vol->bitmap;
739 vol->bitmap = &inode->u.ntfs_i;
740 vol->ino_flags &= ~4;
741 ntfs_free(ino);
742 ino = vol->bitmap;
743 ntfs_debug(DEBUG_OTHER, "Opening $Bitmap!\n");
744 break;
745 case FILE_LogFile ... FILE_AttrDef:
746 /* No need to log root directory accesses. */
747 case FILE_Boot ... FILE_UpCase:
748 ntfs_debug(DEBUG_OTHER, "Opening system file %i!\n",
749 inode->i_ino);
750 default:
751 ino = &inode->u.ntfs_i;
752 if (!ino || ntfs_init_inode(ino, NTFS_INO2VOL(inode),
753 inode->i_ino))
754 {
755 ntfs_debug(DEBUG_OTHER, "NTFS: Error loading inode "
756 "0x%x\n", (unsigned int)inode->i_ino);
757 return;
758 }
759 }
760 /* Set uid/gid from mount options */
761 inode->i_uid = vol->uid;
762 inode->i_gid = vol->gid;
763 inode->i_nlink = 1;
764 /* Use the size of the data attribute as file size */
765 data = ntfs_find_attr(ino, vol->at_data, NULL);
766 if (!data)
767 inode->i_size = 0;
768 else
769 inode->i_size = data->size;
770 /* Get the file modification times from the standard information. */
771 si = ntfs_find_attr(ino, vol->at_standard_information, NULL);
772 if (si) {
773 char *attr = si->d.data;
774 inode->i_atime = ntfs_ntutc2unixutc(NTFS_GETU64(attr + 0x18));
775 inode->i_ctime = ntfs_ntutc2unixutc(NTFS_GETU64(attr));
776 inode->i_mtime = ntfs_ntutc2unixutc(NTFS_GETU64(attr + 8));
777 }
778 /* If it has an index root, it's a directory. */
779 if (ntfs_find_attr(ino, vol->at_index_root, "$I30")) {
780 ntfs_attribute *at;
781 at = ntfs_find_attr(ino, vol->at_index_allocation, "$I30");
782 inode->i_size = at ? at->size : 0;
783 inode->i_op = &ntfs_dir_inode_operations;
784 inode->i_fop = &ntfs_dir_operations;
785 inode->i_mode = S_IFDIR | S_IRUGO | S_IXUGO;
786 } else {
787 inode->i_op = &ntfs_inode_operations;
788 inode->i_fop = &ntfs_file_operations;
789 inode->i_mode = S_IFREG | S_IRUGO;
790 }
791 #ifdef CONFIG_NTFS_RW
792 if (!data || !(data->flags & (ATTR_IS_COMPRESSED | ATTR_IS_ENCRYPTED)))
793 inode->i_mode |= S_IWUGO;
794 #endif
795 inode->i_mode &= ~vol->umask;
796 return;
797 sys_file_error:
798 ntfs_error("Critical error. Tried to call ntfs_read_inode() before we "
799 "have completed read_super() or VFS error.\n");
800 // FIXME: Should we panic() at this stage?
801 }
802
803 #ifdef CONFIG_NTFS_RW
ntfs_write_inode(struct inode * ino,int unused)804 static void ntfs_write_inode(struct inode *ino, int unused)
805 {
806 lock_kernel();
807 ntfs_debug(DEBUG_LINUX, "ntfs_write_inode 0x%x\n", ino->i_ino);
808 ntfs_update_inode(NTFS_LINO2NINO(ino));
809 unlock_kernel();
810 }
811 #endif
812
_ntfs_clear_inode(struct inode * inode)813 static void _ntfs_clear_inode(struct inode *inode)
814 {
815 ntfs_inode *ino;
816 ntfs_volume *vol;
817
818 lock_kernel();
819 ntfs_debug(DEBUG_OTHER, "_ntfs_clear_inode 0x%x\n", inode->i_ino);
820 vol = NTFS_INO2VOL(inode);
821 if (!vol)
822 ntfs_error("_ntfs_clear_inode: vol = NTFS_INO2VOL(inode) is "
823 "NULL.\n");
824 switch (inode->i_ino) {
825 case FILE_Mft:
826 if (vol->mft_ino && ((vol->ino_flags & 1) == 0)) {
827 ino = (ntfs_inode*)ntfs_malloc(sizeof(ntfs_inode));
828 ntfs_memcpy(ino, &inode->u.ntfs_i, sizeof(ntfs_inode));
829 vol->mft_ino = ino;
830 vol->ino_flags |= 1;
831 goto unl_out;
832 }
833 break;
834 case FILE_MftMirr:
835 if (vol->mftmirr && ((vol->ino_flags & 2) == 0)) {
836 ino = (ntfs_inode*)ntfs_malloc(sizeof(ntfs_inode));
837 ntfs_memcpy(ino, &inode->u.ntfs_i, sizeof(ntfs_inode));
838 vol->mftmirr = ino;
839 vol->ino_flags |= 2;
840 goto unl_out;
841 }
842 break;
843 case FILE_BitMap:
844 if (vol->bitmap && ((vol->ino_flags & 4) == 0)) {
845 ino = (ntfs_inode*)ntfs_malloc(sizeof(ntfs_inode));
846 ntfs_memcpy(ino, &inode->u.ntfs_i, sizeof(ntfs_inode));
847 vol->bitmap = ino;
848 vol->ino_flags |= 4;
849 goto unl_out;
850 }
851 break;
852 /* Nothing. Just clear the inode and exit. */
853 }
854 ntfs_clear_inode(&inode->u.ntfs_i);
855 unl_out:
856 unlock_kernel();
857 return;
858 }
859
860 /* Called when umounting a filesystem by do_umount() in fs/super.c. */
ntfs_put_super(struct super_block * sb)861 static void ntfs_put_super(struct super_block *sb)
862 {
863 ntfs_volume *vol;
864
865 ntfs_debug(DEBUG_OTHER, "ntfs_put_super\n");
866 vol = NTFS_SB2VOL(sb);
867 ntfs_release_volume(vol);
868 if (vol->nls_map)
869 unload_nls(vol->nls_map);
870 ntfs_debug(DEBUG_OTHER, "ntfs_put_super: done\n");
871 }
872
873 /* Called by the kernel when asking for stats. */
ntfs_statfs(struct super_block * sb,struct statfs * sf)874 static int ntfs_statfs(struct super_block *sb, struct statfs *sf)
875 {
876 struct inode *mft;
877 ntfs_volume *vol;
878 __s64 size;
879 int error;
880
881 ntfs_debug(DEBUG_OTHER, "ntfs_statfs\n");
882 vol = NTFS_SB2VOL(sb);
883 sf->f_type = NTFS_SUPER_MAGIC;
884 sf->f_bsize = vol->cluster_size;
885 error = ntfs_get_volumesize(NTFS_SB2VOL(sb), &size);
886 if (error)
887 return error;
888 sf->f_blocks = size; /* Volumesize is in clusters. */
889 size = (__s64)ntfs_get_free_cluster_count(vol->bitmap);
890 /* Just say zero if the call failed. */
891 if (size < 0LL)
892 size = 0;
893 sf->f_bfree = sf->f_bavail = size;
894 ntfs_debug(DEBUG_OTHER, "ntfs_statfs: calling mft = iget(sb, "
895 "FILE_Mft)\n");
896 mft = iget(sb, FILE_Mft);
897 ntfs_debug(DEBUG_OTHER, "ntfs_statfs: iget(sb, FILE_Mft) returned "
898 "0x%x\n", mft);
899 if (!mft)
900 return -EIO;
901 sf->f_files = mft->i_size >> vol->mft_record_size_bits;
902 ntfs_debug(DEBUG_OTHER, "ntfs_statfs: calling iput(mft)\n");
903 iput(mft);
904 /* Should be read from volume. */
905 sf->f_namelen = 255;
906 return 0;
907 }
908
909 /* Called when remounting a filesystem by do_remount_sb() in fs/super.c. */
ntfs_remount_fs(struct super_block * sb,int * flags,char * options)910 static int ntfs_remount_fs(struct super_block *sb, int *flags, char *options)
911 {
912 if (!parse_options(NTFS_SB2VOL(sb), options))
913 return -EINVAL;
914 return 0;
915 }
916
917 /* Define the super block operation that are implemented */
918 static struct super_operations ntfs_super_operations = {
919 read_inode: ntfs_read_inode,
920 #ifdef CONFIG_NTFS_RW
921 write_inode: ntfs_write_inode,
922 #endif
923 put_super: ntfs_put_super,
924 statfs: ntfs_statfs,
925 remount_fs: ntfs_remount_fs,
926 clear_inode: _ntfs_clear_inode,
927 };
928
929 /**
930 * is_boot_sector_ntfs - check an NTFS boot sector for validity
931 * @b: buffer containing bootsector to check
932 *
933 * Check whether @b contains a valid NTFS boot sector.
934 * Return 1 if @b is a valid NTFS bootsector or 0 if not.
935 */
is_boot_sector_ntfs(ntfs_u8 * b)936 static int is_boot_sector_ntfs(ntfs_u8 *b)
937 {
938 ntfs_u32 i;
939
940 /* FIXME: We don't use checksumming yet as NT4(SP6a) doesn't either...
941 * But we might as well have the code ready to do it. (AIA) */
942 #if 0
943 /* Calculate the checksum. */
944 if (b < b + 0x50) {
945 ntfs_u32 *u;
946 ntfs_u32 *bi = (ntfs_u32 *)(b + 0x50);
947
948 for (u = bi, i = 0; u < bi; ++u)
949 i += NTFS_GETU32(*u);
950 }
951 #endif
952 /* Check magic is "NTFS " */
953 if (b[3] != 0x4e) goto not_ntfs;
954 if (b[4] != 0x54) goto not_ntfs;
955 if (b[5] != 0x46) goto not_ntfs;
956 if (b[6] != 0x53) goto not_ntfs;
957 for (i = 7; i < 0xb; ++i)
958 if (b[i] != 0x20) goto not_ntfs;
959 /* Check bytes per sector value is between 512 and 4096. */
960 if (b[0xb] != 0) goto not_ntfs;
961 if (b[0xc] > 0x10) goto not_ntfs;
962 /* Check sectors per cluster value is valid. */
963 switch (b[0xd]) {
964 case 1: case 2: case 4: case 8: case 16:
965 case 32: case 64: case 128:
966 break;
967 default:
968 goto not_ntfs;
969 }
970 /* Check reserved sectors value and four other fields are zero. */
971 for (i = 0xe; i < 0x15; ++i)
972 if (b[i] != 0) goto not_ntfs;
973 if (b[0x16] != 0) goto not_ntfs;
974 if (b[0x17] != 0) goto not_ntfs;
975 for (i = 0x20; i < 0x24; ++i)
976 if (b[i] != 0) goto not_ntfs;
977 /* Check clusters per file record segment value is valid. */
978 if (b[0x40] < 0xe1 || b[0x40] > 0xf7) {
979 switch (b[0x40]) {
980 case 1: case 2: case 4: case 8: case 16: case 32: case 64:
981 break;
982 default:
983 goto not_ntfs;
984 }
985 }
986 /* Check clusters per index block value is valid. */
987 if (b[0x44] < 0xe1 || b[0x44] > 0xf7) {
988 switch (b[0x44]) {
989 case 1: case 2: case 4: case 8: case 16: case 32: case 64:
990 break;
991 default:
992 goto not_ntfs;
993 }
994 }
995 return 1;
996 not_ntfs:
997 return 0;
998 }
999
1000 /* Called to mount a filesystem by read_super() in fs/super.c.
1001 * Return a super block, the main structure of a filesystem.
1002 *
1003 * NOTE : Don't store a pointer to an option, as the page containing the
1004 * options is freed after ntfs_read_super() returns.
1005 *
1006 * NOTE : A context switch can happen in kernel code only if the code blocks
1007 * (= calls schedule() in kernel/sched.c). */
ntfs_read_super(struct super_block * sb,void * options,int silent)1008 struct super_block *ntfs_read_super(struct super_block *sb, void *options,
1009 int silent)
1010 {
1011 ntfs_volume *vol;
1012 struct buffer_head *bh;
1013 int i, to_read, blocksize;
1014
1015 ntfs_debug(DEBUG_OTHER, "ntfs_read_super\n");
1016 vol = NTFS_SB2VOL(sb);
1017 init_ntfs_super_block(vol);
1018 if (!parse_options(vol, (char*)options))
1019 goto ntfs_read_super_vol;
1020 blocksize = get_hardsect_size(sb->s_dev);
1021 if (blocksize < 512)
1022 blocksize = 512;
1023 if (set_blocksize(sb->s_dev, blocksize) < 0) {
1024 ntfs_error("Unable to set blocksize %d.\n", blocksize);
1025 goto ntfs_read_super_vol;
1026 }
1027 sb->s_blocksize = blocksize;
1028 /* Read the super block (boot block). */
1029 if (!(bh = sb_bread(sb, 0))) {
1030 ntfs_error("Reading super block failed\n");
1031 goto ntfs_read_super_unl;
1032 }
1033 ntfs_debug(DEBUG_OTHER, "Done reading boot block\n");
1034 /* Check for valid 'NTFS' boot sector. */
1035 if (!is_boot_sector_ntfs(bh->b_data)) {
1036 ntfs_debug(DEBUG_OTHER, "Not a NTFS volume\n");
1037 bforget(bh);
1038 goto ntfs_read_super_unl;
1039 }
1040 ntfs_debug(DEBUG_OTHER, "Going to init volume\n");
1041 if (ntfs_init_volume(vol, bh->b_data) < 0) {
1042 ntfs_debug(DEBUG_OTHER, "Init volume failed.\n");
1043 bforget(bh);
1044 goto ntfs_read_super_unl;
1045 }
1046 ntfs_debug(DEBUG_OTHER, "$Mft at cluster 0x%lx\n", vol->mft_lcn);
1047 brelse(bh);
1048 vol->sb = sb;
1049 if (vol->cluster_size > PAGE_SIZE) {
1050 ntfs_error("Partition cluster size is not supported yet (it "
1051 "is > max kernel blocksize).\n");
1052 goto ntfs_read_super_unl;
1053 }
1054 ntfs_debug(DEBUG_OTHER, "Done to init volume\n");
1055 /* Inform the kernel that a device block is a NTFS cluster. */
1056 sb->s_blocksize = vol->cluster_size;
1057 sb->s_blocksize_bits = vol->cluster_size_bits;
1058 if (blocksize != vol->cluster_size &&
1059 set_blocksize(sb->s_dev, sb->s_blocksize) < 0) {
1060 ntfs_error("Cluster size too small for device.\n");
1061 goto ntfs_read_super_unl;
1062 }
1063 ntfs_debug(DEBUG_OTHER, "set_blocksize\n");
1064 /* Allocate an MFT record (MFT record can be smaller than a cluster). */
1065 i = vol->cluster_size;
1066 if (i < vol->mft_record_size)
1067 i = vol->mft_record_size;
1068 if (!(vol->mft = ntfs_malloc(i)))
1069 goto ntfs_read_super_unl;
1070
1071 /* Read at least the MFT record for $Mft. */
1072 to_read = vol->mft_clusters_per_record;
1073 if (to_read < 1)
1074 to_read = 1;
1075 for (i = 0; i < to_read; i++) {
1076 if (!(bh = sb_bread(sb, vol->mft_lcn + i))) {
1077 ntfs_error("Could not read $Mft record 0\n");
1078 goto ntfs_read_super_mft;
1079 }
1080 ntfs_memcpy(vol->mft + ((__s64)i << vol->cluster_size_bits),
1081 bh->b_data, vol->cluster_size);
1082 brelse(bh);
1083 ntfs_debug(DEBUG_OTHER, "Read cluster 0x%x\n",
1084 vol->mft_lcn + i);
1085 }
1086 /* Check and fixup this MFT record */
1087 if (!ntfs_check_mft_record(vol, vol->mft)){
1088 ntfs_error("Invalid $Mft record 0\n");
1089 goto ntfs_read_super_mft;
1090 }
1091 /* Inform the kernel about which super operations are available. */
1092 sb->s_op = &ntfs_super_operations;
1093 sb->s_magic = NTFS_SUPER_MAGIC;
1094 sb->s_maxbytes = MAX_LFS_FILESIZE;
1095 ntfs_debug(DEBUG_OTHER, "Reading special files\n");
1096 if (ntfs_load_special_files(vol)) {
1097 ntfs_error("Error loading special files\n");
1098 goto ntfs_read_super_mft;
1099 }
1100 ntfs_debug(DEBUG_OTHER, "Getting RootDir\n");
1101 /* Get the root directory. */
1102 if (!(sb->s_root = d_alloc_root(iget(sb, FILE_root)))) {
1103 ntfs_error("Could not get root dir inode\n");
1104 goto ntfs_read_super_mft;
1105 }
1106 ntfs_read_super_ret:
1107 ntfs_debug(DEBUG_OTHER, "read_super: done\n");
1108 return sb;
1109 ntfs_read_super_mft:
1110 ntfs_free(vol->mft);
1111 ntfs_read_super_unl:
1112 ntfs_read_super_vol:
1113 sb = NULL;
1114 goto ntfs_read_super_ret;
1115 }
1116
1117 /* Define the filesystem */
1118 static DECLARE_FSTYPE_DEV(ntfs_fs_type, "ntfs", ntfs_read_super);
1119
init_ntfs_fs(void)1120 static int __init init_ntfs_fs(void)
1121 {
1122 /* Comment this if you trust klogd. There are reasons not to trust it */
1123 #if defined(DEBUG) && !defined(MODULE)
1124 console_verbose();
1125 #endif
1126 printk(KERN_NOTICE "NTFS driver v" NTFS_VERSION " [Flags: R/"
1127 #ifdef CONFIG_NTFS_RW
1128 "W"
1129 #else
1130 "O"
1131 #endif
1132 #ifdef DEBUG
1133 " DEBUG"
1134 #endif
1135 #ifdef MODULE
1136 " MODULE"
1137 #endif
1138 "]\n");
1139 SYSCTL(1);
1140 ntfs_debug(DEBUG_OTHER, "registering %s\n", ntfs_fs_type.name);
1141 /* Add this filesystem to the kernel table of filesystems. */
1142 return register_filesystem(&ntfs_fs_type);
1143 }
1144
exit_ntfs_fs(void)1145 static void __exit exit_ntfs_fs(void)
1146 {
1147 SYSCTL(0);
1148 ntfs_debug(DEBUG_OTHER, "unregistering %s\n", ntfs_fs_type.name);
1149 unregister_filesystem(&ntfs_fs_type);
1150 }
1151
1152 EXPORT_NO_SYMBOLS;
1153 /*
1154 * Not strictly true. The driver was written originally by Martin von L�wis.
1155 * I am just maintaining and rewriting it.
1156 */
1157 MODULE_AUTHOR("Anton Altaparmakov <aia21@cus.cam.ac.uk>");
1158 MODULE_DESCRIPTION("Linux NTFS driver");
1159 MODULE_LICENSE("GPL");
1160 #ifdef DEBUG
1161 MODULE_PARM(ntdebug, "i");
1162 MODULE_PARM_DESC(ntdebug, "Debug level");
1163 #endif
1164
1165 module_init(init_ntfs_fs)
1166 module_exit(exit_ntfs_fs)
1167
1168