mirror of
https://github.com/torvalds/linux.git
synced 2024-11-26 22:21:42 +00:00
NTFS: - Add disable_sparse mount option together with a per volume sparse
enable bit which is set appropriately and a per inode sparse disable bit which is preset on some system file inodes as appropriate. - Enforce that sparse support is disabled on NTFS volumes pre 3.0. Signed-off-by: Anton Altaparmakov <aia21@cantab.net>
This commit is contained in:
parent
f40661be03
commit
c002f42543
@ -21,7 +21,7 @@ Overview
|
||||
========
|
||||
|
||||
Linux-NTFS comes with a number of user-space programs known as ntfsprogs.
|
||||
These include mkntfs, a full-featured ntfs file system format utility,
|
||||
These include mkntfs, a full-featured ntfs filesystem format utility,
|
||||
ntfsundelete used for recovering files that were unintentionally deleted
|
||||
from an NTFS volume and ntfsresize which is used to resize an NTFS partition.
|
||||
See the web site for more information.
|
||||
@ -149,7 +149,14 @@ case_sensitive=<BOOL> If case_sensitive is specified, treat all file names as
|
||||
name, if it exists. If case_sensitive, you will need
|
||||
to provide the correct case of the short file name.
|
||||
|
||||
errors=opt What to do when critical file system errors are found.
|
||||
disable_sparse=<BOOL> If disable_sparse is specified, creation of sparse
|
||||
regions, i.e. holes, inside files is disabled for the
|
||||
volume (for the duration of this mount only). By
|
||||
default, creation of sparse regions is enabled, which
|
||||
is consistent with the behaviour of traditional Unix
|
||||
filesystems.
|
||||
|
||||
errors=opt What to do when critical filesystem errors are found.
|
||||
Following values can be used for "opt":
|
||||
continue: DEFAULT, try to clean-up as much as
|
||||
possible, e.g. marking a corrupt inode as
|
||||
|
@ -56,6 +56,10 @@ ToDo/Notes:
|
||||
this only works until the data attribute becomes too big for the mft
|
||||
record after which we abort the write returning -EOPNOTSUPP from
|
||||
ntfs_prepare_write().
|
||||
- Add disable_sparse mount option together with a per volume sparse
|
||||
enable bit which is set appropriately and a per inode sparse disable
|
||||
bit which is preset on some system file inodes as appropriate.
|
||||
- Enforce that sparse support is disabled on NTFS volumes pre 3.0.
|
||||
|
||||
2.1.22 - Many bug and race fixes and error handling improvements.
|
||||
|
||||
@ -1062,7 +1066,7 @@ tng-0.0.8 - 08/03/2002 - Now using BitKeeper, http://linux-ntfs.bkbits.net/
|
||||
- Further runlist merging work. (Richard Russon)
|
||||
- Backwards compatibility for gcc-2.95. (Richard Russon)
|
||||
- Update to kernel 2.5.5-pre1 and rediff the now tiny patch.
|
||||
- Convert to new file system declaration using ->ntfs_get_sb() and
|
||||
- Convert to new filesystem declaration using ->ntfs_get_sb() and
|
||||
replacing ntfs_read_super() with ntfs_fill_super().
|
||||
- Set s_maxbytes to MAX_LFS_FILESIZE to avoid page cache page index
|
||||
overflow on 32-bit architectures.
|
||||
@ -1358,7 +1362,7 @@ tng-0.0.1 - The first useful version.
|
||||
The driver is now actually useful! Yey. (-: It undoubtedly has got bugs
|
||||
though and it doesn't implement accesssing compressed files yet. Also,
|
||||
accessing files with attribute list attributes is not implemented yet
|
||||
either. But for small or simple file systems it should work and allow
|
||||
either. But for small or simple filesystems it should work and allow
|
||||
you to list directories, use stat on directory entries and the file
|
||||
system, open, read, mmap and llseek around in files. A big mile stone
|
||||
has been reached!
|
||||
@ -1366,7 +1370,7 @@ tng-0.0.1 - The first useful version.
|
||||
tng-0.0.0 - Initial version tag.
|
||||
|
||||
Initial driver implementation. The driver can mount and umount simple
|
||||
NTFS file systems (i.e. ones without attribute lists in the system
|
||||
NTFS filesystems (i.e. ones without attribute lists in the system
|
||||
files). If the mount fails there might be problems in the error handling
|
||||
code paths, so be warned. Otherwise it seems to be loading the system
|
||||
files nicely and the mft record read mapping/unmapping seems to be
|
||||
|
@ -1,7 +1,7 @@
|
||||
/**
|
||||
* dir.c - NTFS kernel directory operations. Part of the Linux-NTFS project.
|
||||
*
|
||||
* Copyright (c) 2001-2004 Anton Altaparmakov
|
||||
* Copyright (c) 2001-2005 Anton Altaparmakov
|
||||
* Copyright (c) 2002 Richard Russon
|
||||
*
|
||||
* This program/include file is free software; you can redistribute it and/or
|
||||
@ -610,7 +610,7 @@ dir_err_out:
|
||||
// TODO: (AIA)
|
||||
// The algorithm embedded in this code will be required for the time when we
|
||||
// want to support adding of entries to directories, where we require correct
|
||||
// collation of file names in order not to cause corruption of the file system.
|
||||
// collation of file names in order not to cause corruption of the filesystem.
|
||||
|
||||
/**
|
||||
* ntfs_lookup_inode_by_name - find an inode in a directory given its name
|
||||
|
@ -1,7 +1,7 @@
|
||||
/**
|
||||
* inode.c - NTFS kernel inode handling. Part of the Linux-NTFS project.
|
||||
*
|
||||
* Copyright (c) 2001-2004 Anton Altaparmakov
|
||||
* Copyright (c) 2001-2005 Anton Altaparmakov
|
||||
*
|
||||
* This program/include file is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as published
|
||||
@ -1731,6 +1731,7 @@ int ntfs_read_inode_mount(struct inode *vi)
|
||||
/* Setup the data attribute. It is special as it is mst protected. */
|
||||
NInoSetNonResident(ni);
|
||||
NInoSetMstProtected(ni);
|
||||
NInoSetSparseDisabled(ni);
|
||||
ni->type = AT_DATA;
|
||||
ni->name = NULL;
|
||||
ni->name_len = 0;
|
||||
@ -2279,6 +2280,8 @@ int ntfs_show_options(struct seq_file *sf, struct vfsmount *mnt)
|
||||
seq_printf(sf, ",case_sensitive");
|
||||
if (NVolShowSystemFiles(vol))
|
||||
seq_printf(sf, ",show_sys_files");
|
||||
if (!NVolSparseEnabled(vol))
|
||||
seq_printf(sf, ",disable_sparse");
|
||||
for (i = 0; on_errors_arr[i].val; i++) {
|
||||
if (on_errors_arr[i].val & vol->on_errors)
|
||||
seq_printf(sf, ",errors=%s", on_errors_arr[i].str);
|
||||
|
@ -2,7 +2,7 @@
|
||||
* inode.h - Defines for inode structures NTFS Linux kernel driver. Part of
|
||||
* the Linux-NTFS project.
|
||||
*
|
||||
* Copyright (c) 2001-2004 Anton Altaparmakov
|
||||
* Copyright (c) 2001-2005 Anton Altaparmakov
|
||||
* Copyright (c) 2002 Richard Russon
|
||||
*
|
||||
* This program/include file is free software; you can redistribute it and/or
|
||||
@ -166,6 +166,7 @@ typedef enum {
|
||||
NI_Sparse, /* 1: Unnamed data attr is sparse (f).
|
||||
1: Create sparse files by default (d).
|
||||
1: Attribute is sparse (a). */
|
||||
NI_SparseDisabled, /* 1: May not create sparse regions. */
|
||||
NI_TruncateFailed, /* 1: Last ntfs_truncate() call failed. */
|
||||
} ntfs_inode_state_bits;
|
||||
|
||||
@ -218,6 +219,7 @@ NINO_FNS(IndexAllocPresent)
|
||||
NINO_FNS(Compressed)
|
||||
NINO_FNS(Encrypted)
|
||||
NINO_FNS(Sparse)
|
||||
NINO_FNS(SparseDisabled)
|
||||
NINO_FNS(TruncateFailed)
|
||||
|
||||
/*
|
||||
|
@ -2,7 +2,7 @@
|
||||
* layout.h - All NTFS associated on-disk structures. Part of the Linux-NTFS
|
||||
* project.
|
||||
*
|
||||
* Copyright (c) 2001-2004 Anton Altaparmakov
|
||||
* Copyright (c) 2001-2005 Anton Altaparmakov
|
||||
* Copyright (c) 2002 Richard Russon
|
||||
*
|
||||
* This program/include file is free software; you can redistribute it and/or
|
||||
@ -834,7 +834,7 @@ enum {
|
||||
/* Note, this is a copy of the corresponding bit from the mft record,
|
||||
telling us whether this file has a view index present (eg. object id
|
||||
index, quota index, one of the security indexes or the encrypting
|
||||
file system related indexes). */
|
||||
filesystem related indexes). */
|
||||
};
|
||||
|
||||
typedef le32 FILE_ATTR_FLAGS;
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* super.c - NTFS kernel super block handling. Part of the Linux-NTFS project.
|
||||
*
|
||||
* Copyright (c) 2001-2004 Anton Altaparmakov
|
||||
* Copyright (c) 2001-2005 Anton Altaparmakov
|
||||
* Copyright (c) 2001,2002 Richard Russon
|
||||
*
|
||||
* This program/include file is free software; you can redistribute it and/or
|
||||
@ -41,7 +41,7 @@
|
||||
#include "malloc.h"
|
||||
#include "ntfs.h"
|
||||
|
||||
/* Number of mounted file systems which have compression enabled. */
|
||||
/* Number of mounted filesystems which have compression enabled. */
|
||||
static unsigned long ntfs_nr_compression_users;
|
||||
|
||||
/* A global default upcase table and a corresponding reference count. */
|
||||
@ -102,7 +102,7 @@ static BOOL parse_options(ntfs_volume *vol, char *opt)
|
||||
gid_t gid = (gid_t)-1;
|
||||
mode_t fmask = (mode_t)-1, dmask = (mode_t)-1;
|
||||
int mft_zone_multiplier = -1, on_errors = -1;
|
||||
int show_sys_files = -1, case_sensitive = -1;
|
||||
int show_sys_files = -1, case_sensitive = -1, disable_sparse = -1;
|
||||
struct nls_table *nls_map = NULL, *old_nls;
|
||||
|
||||
/* I am lazy... (-8 */
|
||||
@ -162,6 +162,7 @@ static BOOL parse_options(ntfs_volume *vol, char *opt)
|
||||
else NTFS_GETOPT_WITH_DEFAULT("sloppy", sloppy, TRUE)
|
||||
else NTFS_GETOPT_BOOL("show_sys_files", show_sys_files)
|
||||
else NTFS_GETOPT_BOOL("case_sensitive", case_sensitive)
|
||||
else NTFS_GETOPT_BOOL("disable_sparse", disable_sparse)
|
||||
else NTFS_GETOPT_OPTIONS_ARRAY("errors", on_errors,
|
||||
on_errors_arr)
|
||||
else if (!strcmp(p, "posix") || !strcmp(p, "show_inodes"))
|
||||
@ -291,6 +292,21 @@ no_mount_options:
|
||||
else
|
||||
NVolClearCaseSensitive(vol);
|
||||
}
|
||||
if (disable_sparse != -1) {
|
||||
if (disable_sparse)
|
||||
NVolClearSparseEnabled(vol);
|
||||
else {
|
||||
if (!NVolSparseEnabled(vol) &&
|
||||
vol->major_ver && vol->major_ver < 3)
|
||||
ntfs_warning(vol->sb, "Not enabling sparse "
|
||||
"support due to NTFS volume "
|
||||
"version %i.%i (need at least "
|
||||
"version 3.0).", vol->major_ver,
|
||||
vol->minor_ver);
|
||||
else
|
||||
NVolSetSparseEnabled(vol);
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
needs_arg:
|
||||
ntfs_error(vol->sb, "The %s option requires an argument.", p);
|
||||
@ -967,6 +983,7 @@ static BOOL load_and_init_mft_mirror(ntfs_volume *vol)
|
||||
tmp_ni = NTFS_I(tmp_ino);
|
||||
/* The $MFTMirr, like the $MFT is multi sector transfer protected. */
|
||||
NInoSetMstProtected(tmp_ni);
|
||||
NInoSetSparseDisabled(tmp_ni);
|
||||
/*
|
||||
* Set up our little cheat allowing us to reuse the async read io
|
||||
* completion handler for directories.
|
||||
@ -1122,6 +1139,7 @@ static BOOL load_and_check_logfile(ntfs_volume *vol)
|
||||
/* ntfs_check_logfile() will have displayed error output. */
|
||||
return FALSE;
|
||||
}
|
||||
NInoSetSparseDisabled(NTFS_I(tmp_ino));
|
||||
vol->logfile_ino = tmp_ino;
|
||||
ntfs_debug("Done.");
|
||||
return TRUE;
|
||||
@ -1220,6 +1238,7 @@ static BOOL load_and_init_attrdef(ntfs_volume *vol)
|
||||
iput(ino);
|
||||
goto failed;
|
||||
}
|
||||
NInoSetSparseDisabled(NTFS_I(ino));
|
||||
/* The size of FILE_AttrDef must be above 0 and fit inside 31 bits. */
|
||||
i_size = i_size_read(ino);
|
||||
if (i_size <= 0 || i_size > 0x7fffffff)
|
||||
@ -1439,6 +1458,7 @@ static BOOL load_system_files(ntfs_volume *vol)
|
||||
iput(vol->lcnbmp_ino);
|
||||
goto bitmap_failed;
|
||||
}
|
||||
NInoSetSparseDisabled(NTFS_I(vol->lcnbmp_ino));
|
||||
if ((vol->nr_clusters + 7) >> 3 > i_size_read(vol->lcnbmp_ino)) {
|
||||
iput(vol->lcnbmp_ino);
|
||||
bitmap_failed:
|
||||
@ -1490,6 +1510,12 @@ get_ctx_vol_failed:
|
||||
unmap_mft_record(NTFS_I(vol->vol_ino));
|
||||
printk(KERN_INFO "NTFS volume version %i.%i.\n", vol->major_ver,
|
||||
vol->minor_ver);
|
||||
if (vol->major_ver < 3 && NVolSparseEnabled(vol)) {
|
||||
ntfs_warning(vol->sb, "Disabling sparse support due to NTFS "
|
||||
"volume version %i.%i (need at least version "
|
||||
"3.0).", vol->major_ver, vol->minor_ver);
|
||||
NVolClearSparseEnabled(vol);
|
||||
}
|
||||
#ifdef NTFS_RW
|
||||
/* Make sure that no unsupported volume flags are set. */
|
||||
if (vol->vol_flags & VOLUME_MUST_MOUNT_RO_MASK) {
|
||||
@ -2033,7 +2059,7 @@ static s64 get_nr_free_clusters(ntfs_volume *vol)
|
||||
/**
|
||||
* __get_nr_free_mft_records - return the number of free inodes on a volume
|
||||
* @vol: ntfs volume for which to obtain free inode count
|
||||
* @nr_free: number of mft records in file system
|
||||
* @nr_free: number of mft records in filesystem
|
||||
* @max_index: maximum number of pages containing set bits
|
||||
*
|
||||
* Calculate the number of free mft records (inodes) on the mounted NTFS
|
||||
@ -2138,13 +2164,13 @@ static int ntfs_statfs(struct super_block *sb, struct kstatfs *sfs)
|
||||
/* Optimal transfer block size. */
|
||||
sfs->f_bsize = PAGE_CACHE_SIZE;
|
||||
/*
|
||||
* Total data blocks in file system in units of f_bsize and since
|
||||
* Total data blocks in filesystem in units of f_bsize and since
|
||||
* inodes are also stored in data blocs ($MFT is a file) this is just
|
||||
* the total clusters.
|
||||
*/
|
||||
sfs->f_blocks = vol->nr_clusters << vol->cluster_size_bits >>
|
||||
PAGE_CACHE_SHIFT;
|
||||
/* Free data blocks in file system in units of f_bsize. */
|
||||
/* Free data blocks in filesystem in units of f_bsize. */
|
||||
size = get_nr_free_clusters(vol) << vol->cluster_size_bits >>
|
||||
PAGE_CACHE_SHIFT;
|
||||
if (size < 0LL)
|
||||
@ -2163,7 +2189,7 @@ static int ntfs_statfs(struct super_block *sb, struct kstatfs *sfs)
|
||||
max_index = ((((mft_ni->initialized_size >> vol->mft_record_size_bits)
|
||||
+ 7) >> 3) + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
|
||||
read_unlock_irqrestore(&mft_ni->size_lock, flags);
|
||||
/* Number of inodes in file system (at this point in time). */
|
||||
/* Number of inodes in filesystem (at this point in time). */
|
||||
sfs->f_files = size;
|
||||
/* Free inodes in fs (based on current total count). */
|
||||
sfs->f_ffree = __get_nr_free_mft_records(vol, size, max_index);
|
||||
@ -2172,8 +2198,8 @@ static int ntfs_statfs(struct super_block *sb, struct kstatfs *sfs)
|
||||
* File system id. This is extremely *nix flavour dependent and even
|
||||
* within Linux itself all fs do their own thing. I interpret this to
|
||||
* mean a unique id associated with the mounted fs and not the id
|
||||
* associated with the file system driver, the latter is already given
|
||||
* by the file system type in sfs->f_type. Thus we use the 64-bit
|
||||
* associated with the filesystem driver, the latter is already given
|
||||
* by the filesystem type in sfs->f_type. Thus we use the 64-bit
|
||||
* volume serial number splitting it into two 32-bit parts. We enter
|
||||
* the least significant 32-bits in f_fsid[0] and the most significant
|
||||
* 32-bits in f_fsid[1].
|
||||
@ -2259,18 +2285,18 @@ static struct export_operations ntfs_export_ops = {
|
||||
};
|
||||
|
||||
/**
|
||||
* ntfs_fill_super - mount an ntfs files system
|
||||
* @sb: super block of ntfs file system to mount
|
||||
* ntfs_fill_super - mount an ntfs filesystem
|
||||
* @sb: super block of ntfs filesystem to mount
|
||||
* @opt: string containing the mount options
|
||||
* @silent: silence error output
|
||||
*
|
||||
* ntfs_fill_super() is called by the VFS to mount the device described by @sb
|
||||
* with the mount otions in @data with the NTFS file system.
|
||||
* with the mount otions in @data with the NTFS filesystem.
|
||||
*
|
||||
* If @silent is true, remain silent even if errors are detected. This is used
|
||||
* during bootup, when the kernel tries to mount the root file system with all
|
||||
* registered file systems one after the other until one succeeds. This implies
|
||||
* that all file systems except the correct one will quite correctly and
|
||||
* during bootup, when the kernel tries to mount the root filesystem with all
|
||||
* registered filesystems one after the other until one succeeds. This implies
|
||||
* that all filesystems except the correct one will quite correctly and
|
||||
* expectedly return an error, but nobody wants to see error messages when in
|
||||
* fact this is what is supposed to happen.
|
||||
*
|
||||
@ -2330,6 +2356,9 @@ static int ntfs_fill_super(struct super_block *sb, void *opt, const int silent)
|
||||
|
||||
unlock_kernel();
|
||||
|
||||
/* By default, enable sparse support. */
|
||||
NVolSetSparseEnabled(vol);
|
||||
|
||||
/* Important to get the mount options dealt with now. */
|
||||
if (!parse_options(vol, (char*)opt))
|
||||
goto err_out_now;
|
||||
@ -2711,7 +2740,7 @@ static int __init init_ntfs_fs(void)
|
||||
ntfs_debug("NTFS driver registered successfully.");
|
||||
return 0; /* Success! */
|
||||
}
|
||||
printk(KERN_CRIT "NTFS: Failed to register NTFS file system driver!\n");
|
||||
printk(KERN_CRIT "NTFS: Failed to register NTFS filesystem driver!\n");
|
||||
|
||||
sysctl_err_out:
|
||||
kmem_cache_destroy(ntfs_big_inode_cache);
|
||||
@ -2725,7 +2754,7 @@ actx_err_out:
|
||||
kmem_cache_destroy(ntfs_index_ctx_cache);
|
||||
ictx_err_out:
|
||||
if (!err) {
|
||||
printk(KERN_CRIT "NTFS: Aborting NTFS file system driver "
|
||||
printk(KERN_CRIT "NTFS: Aborting NTFS filesystem driver "
|
||||
"registration...\n");
|
||||
err = -ENOMEM;
|
||||
}
|
||||
@ -2765,7 +2794,7 @@ static void __exit exit_ntfs_fs(void)
|
||||
}
|
||||
|
||||
MODULE_AUTHOR("Anton Altaparmakov <aia21@cantab.net>");
|
||||
MODULE_DESCRIPTION("NTFS 1.2/3.x driver - Copyright (c) 2001-2004 Anton Altaparmakov");
|
||||
MODULE_DESCRIPTION("NTFS 1.2/3.x driver - Copyright (c) 2001-2005 Anton Altaparmakov");
|
||||
MODULE_VERSION(NTFS_VERSION);
|
||||
MODULE_LICENSE("GPL");
|
||||
#ifdef DEBUG
|
||||
|
@ -3,7 +3,7 @@
|
||||
* the Linux-NTFS project. Adapted from the old NTFS driver,
|
||||
* Copyright (C) 1997 Martin von Löwis, Régis Duchesne
|
||||
*
|
||||
* Copyright (c) 2002-2004 Anton Altaparmakov
|
||||
* Copyright (c) 2002-2005 Anton Altaparmakov
|
||||
*
|
||||
* This program/include file is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as published
|
||||
@ -67,7 +67,7 @@ int ntfs_sysctl(int add)
|
||||
return -ENOMEM;
|
||||
#ifdef CONFIG_PROC_FS
|
||||
/*
|
||||
* If the proc file system is in use and we are a module, need
|
||||
* If the proc filesystem is in use and we are a module, need
|
||||
* to set the owner of our proc entry to our module. In the
|
||||
* non-modular case, THIS_MODULE is NULL, so this is ok.
|
||||
*/
|
||||
|
@ -2,7 +2,7 @@
|
||||
* volume.h - Defines for volume structures in NTFS Linux kernel driver. Part
|
||||
* of the Linux-NTFS project.
|
||||
*
|
||||
* Copyright (c) 2001-2004 Anton Altaparmakov
|
||||
* Copyright (c) 2001-2005 Anton Altaparmakov
|
||||
* Copyright (c) 2002 Richard Russon
|
||||
*
|
||||
* This program/include file is free software; you can redistribute it and/or
|
||||
@ -54,7 +54,7 @@ typedef struct {
|
||||
mode_t dmask; /* The mask for directory
|
||||
permissions. */
|
||||
u8 mft_zone_multiplier; /* Initial mft zone multiplier. */
|
||||
u8 on_errors; /* What to do on file system errors. */
|
||||
u8 on_errors; /* What to do on filesystem errors. */
|
||||
/* NTFS bootsector provided information. */
|
||||
u16 sector_size; /* in bytes */
|
||||
u8 sector_size_bits; /* log2(sector_size) */
|
||||
@ -141,6 +141,7 @@ typedef enum {
|
||||
file names in WIN32 namespace. */
|
||||
NV_LogFileEmpty, /* 1: $LogFile journal is empty. */
|
||||
NV_QuotaOutOfDate, /* 1: $Quota is out of date. */
|
||||
NV_SparseEnabled, /* 1: May create sparse files. */
|
||||
} ntfs_volume_flags;
|
||||
|
||||
/*
|
||||
@ -167,5 +168,6 @@ NVOL_FNS(ShowSystemFiles)
|
||||
NVOL_FNS(CaseSensitive)
|
||||
NVOL_FNS(LogFileEmpty)
|
||||
NVOL_FNS(QuotaOutOfDate)
|
||||
NVOL_FNS(SparseEnabled)
|
||||
|
||||
#endif /* _LINUX_NTFS_VOLUME_H */
|
||||
|
Loading…
Reference in New Issue
Block a user