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:
Anton Altaparmakov 2005-02-03 12:02:56 +00:00
parent f40661be03
commit c002f42543
9 changed files with 80 additions and 33 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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);

View File

@ -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)
/*

View File

@ -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;

View File

@ -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

View File

@ -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.
*/

View File

@ -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 */