📄 fs.c
字号:
if (*value) { printk(KERN_ERR "NTFS: umask invalid " "argument\n"); return 0; } } else if (strcmp(opt, "mft_zone_multiplier") == 0) { unsigned long ul; if (!value || !*value) goto needs_arg; ul = simple_strtoul(value, &value, 0); if (*value) { printk(KERN_ERR "NTFS: mft_zone_multiplier " "invalid argument\n"); return 0; } if (ul >= 1 && ul <= 4) mft_zone_mul = ul; else { mft_zone_mul = 1; printk(KERN_WARNING "NTFS: mft_zone_multiplier " "out of range. Setting to 1.\n"); } } else if (strcmp(opt, "posix") == 0) { int val; if (!value || !*value) goto needs_arg; if (!simple_getbool(value, &val)) goto needs_bool; ngt = val ? ngt_posix : ngt_nt; } else if (strcmp(opt, "show_sys_files") == 0) { int val = 0; if (!value || !*value) val = 1; else if (!simple_getbool(value, &val)) goto needs_bool; ngt = val ? ngt_full : ngt_nt; } else if (strcmp(opt, "iocharset") == 0) { if (!value || !*value) goto needs_arg; nls_map = load_nls(value); if (!nls_map) { printk(KERN_ERR "NTFS: charset not found"); return 0; } } else if (strcmp(opt, "utf8") == 0) { int val = 0; if (!value || !*value) val = 1; else if (!simple_getbool(value, &val)) goto needs_bool; use_utf8 = val; } else { printk(KERN_ERR "NTFS: unkown option '%s'\n", opt); return 0; } }done: if (use_utf8 == -1) { /* utf8 was not specified at all. */ if (!nls_map) { /* * No NLS was specified. If first mount, load the * default NLS, otherwise don't change the NLS setting. */ if (vol->nls_map == (void*)-1) vol->nls_map = load_nls_default(); } else { /* If an NLS was already loaded, unload it first. */ if (vol->nls_map && vol->nls_map != (void*)-1) unload_nls(vol->nls_map); /* Use the specified NLS. */ vol->nls_map = nls_map; } } else { /* utf8 was specified. */ if (use_utf8 && nls_map) { unload_nls(nls_map); printk(KERN_ERR "NTFS: utf8 cannot be combined with " "iocharset.\n"); return 0; } /* If an NLS was already loaded, unload it first. */ if (vol->nls_map && vol->nls_map != (void*)-1) unload_nls(vol->nls_map); if (!use_utf8) { /* utf8 was specified as false. */ if (!nls_map) /* No NLS was specified, load the default. */ vol->nls_map = load_nls_default(); else /* Use the specified NLS. */ vol->nls_map = nls_map; } else /* utf8 was specified as true. */ vol->nls_map = NULL; } if (uid != -1) vol->uid = uid; if (gid != -1) vol->gid = gid; if (umask != -1) vol->umask = (ntmode_t)umask; if (ngt != -1) vol->ngt = ngt; if (mft_zone_mul != -1) { /* mft_zone_multiplier was specified. */ if (vol->mft_zone_multiplier != -1) { /* This is a remount, ignore a change and warn user. */ if (vol->mft_zone_multiplier != mft_zone_mul) printk(KERN_WARNING "NTFS: Ignoring changes in " "mft_zone_multiplier on " "remount. If you want to " "change this you need to " "umount and mount again.\n"); } else /* Use the specified multiplier. */ vol->mft_zone_multiplier = mft_zone_mul; } else if (vol->mft_zone_multiplier == -1) /* No multiplier specified and first mount, so set default. */ vol->mft_zone_multiplier = 1; return 1;needs_arg: printk(KERN_ERR "NTFS: %s needs an argument", opt); return 0;needs_bool: printk(KERN_ERR "NTFS: %s needs boolean argument", opt); return 0;} static struct dentry *ntfs_lookup(struct inode *dir, struct dentry *d){ struct inode *res = 0; char *item = 0; ntfs_iterate_s walk; int err; ntfs_debug(DEBUG_NAME1, __FUNCTION__ "(): Looking up %s in directory " "ino 0x%x.\n", d->d_name.name, (unsigned)dir->i_ino); walk.name = NULL; walk.namelen = 0; /* Convert to wide string. */ err = ntfs_decodeuni(NTFS_INO2VOL(dir), (char*)d->d_name.name, d->d_name.len, &walk.name, &walk.namelen); if (err) goto err_ret; item = ntfs_malloc(ITEM_SIZE); if (!item) { err = -ENOMEM; goto err_ret; } /* ntfs_getdir will place the directory entry into item, and the first * long long is the MFT record number. */ walk.type = BY_NAME; walk.dir = NTFS_LINO2NINO(dir); walk.result = item; if (ntfs_getdir_byname(&walk)) res = iget(dir->i_sb, NTFS_GETU32(item)); d_add(d, res); ntfs_free(item); ntfs_free(walk.name); /* Always return success, the dcache will handle negative entries. */ return NULL;err_ret: ntfs_free(walk.name); return ERR_PTR(err);}static struct file_operations ntfs_file_operations = { llseek: generic_file_llseek, read: ntfs_read,#ifdef CONFIG_NTFS_RW write: ntfs_write,#endif open: generic_file_open,};static struct inode_operations ntfs_inode_operations;#ifdef CONFIG_NTFS_RWstatic int ntfs_create(struct inode* dir, struct dentry *d, int mode){ struct inode *r = 0; ntfs_inode *ino = 0; ntfs_volume *vol; int error = 0; ntfs_attribute *si; r = new_inode(dir->i_sb); if (!r) { error = -ENOMEM; goto fail; } ntfs_debug(DEBUG_OTHER, "ntfs_create %s\n", d->d_name.name); vol = NTFS_INO2VOL(dir); ino = NTFS_LINO2NINO(r); error = ntfs_alloc_file(NTFS_LINO2NINO(dir), ino, (char*)d->d_name.name, d->d_name.len); if (error) { ntfs_error("ntfs_alloc_file FAILED: error = %i", error); goto fail; } /* Not doing this one was causing a huge amount of corruption! Now the * bugger bytes the dust! (-8 (AIA) */ r->i_ino = ino->i_number; error = ntfs_update_inode(ino); if (error) goto fail; error = ntfs_update_inode(NTFS_LINO2NINO(dir)); if (error) goto fail; r->i_uid = vol->uid; r->i_gid = vol->gid; /* FIXME: dirty? dev? */ /* Get the file modification times from the standard information. */ si = ntfs_find_attr(ino, vol->at_standard_information, NULL); if (si) { char *attr = si->d.data; r->i_atime = ntfs_ntutc2unixutc(NTFS_GETU64(attr + 0x18)); r->i_ctime = ntfs_ntutc2unixutc(NTFS_GETU64(attr)); r->i_mtime = ntfs_ntutc2unixutc(NTFS_GETU64(attr + 8)); } /* It's not a directory */ r->i_op = &ntfs_inode_operations; r->i_fop = &ntfs_file_operations; r->i_mode = S_IFREG | S_IRUGO;#ifdef CONFIG_NTFS_RW r->i_mode |= S_IWUGO;#endif r->i_mode &= ~vol->umask; insert_inode_hash(r); d_instantiate(d, r); return 0; fail: if (r) iput(r); return error;}static int _linux_ntfs_mkdir(struct inode *dir, struct dentry* d, int mode){ int error; struct inode *r = 0; ntfs_volume *vol; ntfs_inode *ino; ntfs_attribute *si; ntfs_debug (DEBUG_DIR1, "mkdir %s in %x\n", d->d_name.name, dir->i_ino); error = -ENAMETOOLONG; if (d->d_name.len > /* FIXME: */ 255) goto out; error = -EIO; r = new_inode(dir->i_sb); if (!r) goto out; vol = NTFS_INO2VOL(dir); ino = NTFS_LINO2NINO(r); error = ntfs_mkdir(NTFS_LINO2NINO(dir), d->d_name.name, d->d_name.len, ino); if (error) goto out; /* Not doing this one was causing a huge amount of corruption! Now the * bugger bytes the dust! (-8 (AIA) */ r->i_ino = ino->i_number; r->i_uid = vol->uid; r->i_gid = vol->gid; si = ntfs_find_attr(ino, vol->at_standard_information, NULL); if (si) { char *attr = si->d.data; r->i_atime = ntfs_ntutc2unixutc(NTFS_GETU64(attr + 0x18)); r->i_ctime = ntfs_ntutc2unixutc(NTFS_GETU64(attr)); r->i_mtime = ntfs_ntutc2unixutc(NTFS_GETU64(attr + 8)); } /* It's a directory. */ r->i_op = &ntfs_dir_inode_operations; r->i_fop = &ntfs_dir_operations; r->i_mode = S_IFDIR | S_IRUGO | S_IXUGO;#ifdef CONFIG_NTFS_RW r->i_mode |= S_IWUGO;#endif r->i_mode &= ~vol->umask; insert_inode_hash(r); d_instantiate(d, r); error = 0; out: ntfs_debug (DEBUG_DIR1, "mkdir returns %d\n", error); return error;}#endifstatic struct file_operations ntfs_dir_operations = { read: generic_read_dir, readdir: ntfs_readdir,};static struct inode_operations ntfs_dir_inode_operations = { lookup: ntfs_lookup,#ifdef CONFIG_NTFS_RW create: ntfs_create, mkdir: _linux_ntfs_mkdir,#endif};/* ntfs_read_inode() is called by the Virtual File System (the kernel layer * that deals with filesystems) when iget is called requesting an inode not * already present in the inode table. Typically filesystems have separate * inode_operations for directories, files and symlinks. */static void ntfs_read_inode(struct inode* inode){ ntfs_volume *vol; ntfs_inode *ino; ntfs_attribute *data; ntfs_attribute *si; vol = NTFS_INO2VOL(inode); inode->i_mode = 0; ntfs_debug(DEBUG_OTHER, "ntfs_read_inode 0x%lx\n", inode->i_ino); switch (inode->i_ino) { /* Those are loaded special files. */ case FILE_Mft: if (!vol->mft_ino || ((vol->ino_flags & 1) == 0)) goto sys_file_error; ntfs_memcpy(&inode->u.ntfs_i, vol->mft_ino, sizeof(ntfs_inode)); ino = vol->mft_ino; vol->mft_ino = &inode->u.ntfs_i; vol->ino_flags &= ~1; ntfs_free(ino); ino = vol->mft_ino; ntfs_debug(DEBUG_OTHER, "Opening $MFT!\n"); break; case FILE_MftMirr: if (!vol->mftmirr || ((vol->ino_flags & 2) == 0)) goto sys_file_error; ntfs_memcpy(&inode->u.ntfs_i, vol->mftmirr, sizeof(ntfs_inode)); ino = vol->mftmirr; vol->mftmirr = &inode->u.ntfs_i; vol->ino_flags &= ~2; ntfs_free(ino); ino = vol->mftmirr; ntfs_debug(DEBUG_OTHER, "Opening $MFTMirr!\n"); break; case FILE_BitMap: if (!vol->bitmap || ((vol->ino_flags & 4) == 0)) goto sys_file_error; ntfs_memcpy(&inode->u.ntfs_i, vol->bitmap, sizeof(ntfs_inode)); ino = vol->bitmap; vol->bitmap = &inode->u.ntfs_i; vol->ino_flags &= ~4; ntfs_free(ino); ino = vol->bitmap; ntfs_debug(DEBUG_OTHER, "Opening $Bitmap!\n"); break; case FILE_LogFile ... FILE_AttrDef: /* No need to log root directory accesses. */ case FILE_Boot ... FILE_UpCase: ntfs_debug(DEBUG_OTHER, "Opening system file %i!\n", inode->i_ino); default: ino = &inode->u.ntfs_i; if (!ino || ntfs_init_inode(ino, NTFS_INO2VOL(inode), inode->i_ino)) { ntfs_debug(DEBUG_OTHER, "NTFS: Error loading inode " "0x%x\n", (unsigned int)inode->i_ino); return; } } /* Set uid/gid from mount options */ inode->i_uid = vol->uid; inode->i_gid = vol->gid; inode->i_nlink = 1; /* Use the size of the data attribute as file size */ data = ntfs_find_attr(ino, vol->at_data, NULL); if (!data) inode->i_size = 0; else inode->i_size = data->size; /* Get the file modification times from the standard information. */ si = ntfs_find_attr(ino, vol->at_standard_information, NULL); if (si) { char *attr = si->d.data; inode->i_atime = ntfs_ntutc2unixutc(NTFS_GETU64(attr + 0x18)); inode->i_ctime = ntfs_ntutc2unixutc(NTFS_GETU64(attr)); inode->i_mtime = ntfs_ntutc2unixutc(NTFS_GETU64(attr + 8)); } /* If it has an index root, it's a directory. */ if (ntfs_find_attr(ino, vol->at_index_root, "$I30")) { ntfs_attribute *at;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -