Windows requires non-Microsoft reparse points (identified by having bit
31 of the reparse tag clear) to have a 16-byte GUID following the regular
reparse point header. This GUID is not, and cannot, be included in the
"reparse data length" field.
(Contributed by Eric Biggers)
Under some rare condition there is no space in an MFT entry to make
an index non-resident, and the index root has to be moved to an extent.
This fix cares for the situation when the attribute list was inserted
beforehand.
When writing to compressed data, the function ntfs_attr_pwrite()
cannot cross a compression block border. This is a problem for archivers
which rely on libntfs-3g, so the function is now wrapped in another one
which restarts the writing as needed.
ntfs_valid_sid() required that the subauthority count be between 1 and 8
inclusively. However, Windows permits more than 8 subauthorities as well
as 0 subauthorities:
- The install.wim file for the latest Windows 10 build contains a file
whose DACL contains a SID with 10 subauthorities.
ntfs_set_ntfs_acl() was failing on this file.
- The IsValidSid() function on Windows returns true for subauthority
less than or equal to 15, including 0.
There was actually already a another SID validation function that had the
Windows-compatible behavior, so I merged the two together.
Contributed by Eric Biggers
Compressed records may be written as full clusters even though cluster
tails are meaningless. This is to avoid the lower levels doing a read-
modify-write cycle. Be sure to zero the meaningless bytes to avoid
leaking information.
Contributed by Eric Biggers
When the owner and the group of a file have the same SID, and permissions
for the group is the same as permissions for other, no ACE is needed for
the group.
Newer versions of Windows use more recent definitions of upper-case
table defined by the Unicode consortium. Now using the same table as
Windows 7, windows 8 and Windows 10. This only has an effect on file
systems newly created by mkntfs.
An unused MFT record may show a bad length, leading to fetch fixups from
unallocated memory when allocating the record to a new file. So check
the length before applying the fixups. Such records have been found after
the MFT has been reallocated by a defragmenter, and they are not cleaned
by chkdsk.
When chmod'ing a file, no new ACL has to be created if the one needed
is already present in the cache. However the read-only flag may have
to be updated, so that it is kept as the opposite of S_IWUSR.
When the security attribute is present, chkdsk may set a null security id
in the standard attributes, and this should not be considered as an error.
(this partially reverts commit [70e5b1])
This patch changes the algorithm to use hash chains instead of binary
trees, with much stronger hashing. It also introduces useful (for
performance) parameters, such as the "nice match length" and "maximum
search depth", that are similar to those used in other commonly used
compression algorithms such as zlib's DEFLATE implementation.
The speed improvement is very significant, with some loss of compression
rate. The compression rate is still better than then Windows one.
Contributed by Eric Biggers
The new way goes via /sys/dev/block/MAJOR:MINOR to map partitions to
devices and get discard parameters of the parent device. It also ensures
that the partition is aligned to the discard block size.
Contributed by Richard W.M. Jones
fstrim(8) discards unused blocks on a mounted filesystem. It is useful for
solid-state drives (SSDs) and thinly-provisioned storage.
Only trimming the full device (with no option) is supported.
Contributed by Richard W.M. Jones
When Posix ACLs are used, the umask is ignored and the initial permissions
of created files are taken for the parent directory. However the umask
should still be used when the Posix ACLs are not enabled in the mount
options.
Ownership of files should always represent the creator of files.
This fixes a situation, currently disabled, where there is no user
mapping and the owner of the parent directory is used as the owner
of the created file.
When using Windows inheritance, the cacheing of ACLs for files created
within a directory only depended on the directory. Actually it also
depends on the user who creates the file. With the patch, only the ACLs
created by the owner of the directory are cached.
When grouping of users are determined from /etc/group (a compile-time
option not currently used), the groups examined for checking access rights
to a file were wrongly derived from the uid of the file instead of the
uid of the current process.
Since Vista, the standard directory /Users/Public which should be accessed
by any user is actually restricted to a few group of users, among them
the interactive ones. To make this directory accessible without using
the Posix ACLs, all Linux users are considered as interactive.
However, when Posix ACLs are used, users supposed to be interactive have
to be put into a secondary group mapped to the equivalent Windows group.
When using the Windows permission inheritance mode and the current user
has not been mapped, try to derive a reasonable user from the parent
directory.
The Windows-type inheritance of an ACE may imply creating two ACE's : one
for access and one for further inheritance. The conditions for doing so,
and the flags set on created ACE were sometimes wrong.
Note : the rules have been derived from testing multiple situations, but
there still are some gray cases.
Since Vista, Windows defines a /Users/Public directory supposed to be
public, but actually only allowed to a few user categories (interactive,
batch, etc.) This patch makes possible to create equivalent Unix groups
and group users the same way as in Windows. Posix ACLs have to be enabled
for access to /Users/Public to be allowed to several groups.
chkdsk deletes the ACLs when they are bad or when they are not used any
more. This fixes inserting a new ACL after the previously last ACL (or
even all of them) was deleted.
A bug was introduced by commit d2c7d40a2b :
when the beginning of a file was a hole and the runlist span over several
MFT extents, the runlist was not mapped on filling the initial hole.
This lead to a crash when using torrent to download big files.
Windows applies legacy restrictions to file names, so when the option
windows_names is applied, reject the same reserved names, which are
CON, PRN, AUX, NUL, COM1..COM9, and LPT1..LPT9
When the runlist of the data attribute of MFT has to be split across
several extents, the location of each extent has to be known from the
runlist present in previous extents. So, force the first extent into
record 15 to avoid a bad layout.
When a hole in a sparse file was filled, the runlist was fully recomputed.
When a sparse file spans over several MFT extents, this patch leads to
only recompute the runlist from the modified extent to the end.
Updating an attribute may imply decompressing runlists which are not
contiguous, leaving an unmapped region between them. When checking whether
the attribute has been made sparse, such unmapped regions should be ignored
This mostly happens after updating an index. (fix by Forrest Liu)
Windows server 2012 apparently uses files with no ACEs in their DACL,
thus denying any access to any process except system backup.
Such DACLs should however be considered valid.
When calling ntfstruncate() to expand a resident attribute, the function
is called again recursively, losing the requirement for not inserting
holes. This is for forwarding the requirement (used by ntfscp).
When testing whether a stream has been wiped out for possibly changing
its compression status, only the non-resident case was considered.
This fixes the test for streams which were never made non-resident.
Windows 8 does not zero any more the end of a compression block beyond
what is needed to reach the end of a file. We must now be careful not
to decompress more data than needed.
When translating Windows-type symlinks to Linux ones, the directory
separator has to be changed from '\' to '/'. The change was wrong
for multiple "..\" and ".\"
The file /etc/mtab is traditionally checked to avoid multiple mountings
of the same device, but this is not accurate enough in some conditions.
So use /proc/mounts when available and fall back to /etc/mtab on
systems which do not have /proc/mounts.
Author: Anton Altaparmakov <anton@tuxera.com>
Date: Tue Feb 12 10:33:55 2013 +0000
Modify libntfs-3g to make use of hd library to get the legacy BIOS geometry
from EDD. We scan all whole disk devices on the system and check if they
match the open ntfs device and if not we scan all partition devices on the
system and check if they match the open ntfs device.
If we find a partition device to match then we find its parent device again
using the hd library.
Once we have the parent of the partition device or we matched a whole disk
device we get the legacy EDD sectors per track and heads again using the hd
library.
Use of the hd library is auto detected (based on finding <hd.h> header file,
being able to link against libhd and finding the hd_list symbol in libhd.
Use can also be disabled/enabled/libhd prefix specified at ./configure time.
See ./configure --help for details.
Note this obviously requires libhd to be installed. On Ubuntu 12/04 systems
the relevant packages needed are libhd-dev and libhd16 (on older Ubuntu
versions it will be libhdN where N is some number <= 16 but an easy way to
get the right package is to simply install libhd-dev which by dependency
pulls in the correct libhdN package) whilst on SLES systems the relevant
packages needed are hwinfo and hwinfo-devel.
Upgrade the Win32 interface (win32_io.c) which was designed for Cygwin
so that it can be used for using the ntfsprogs utilities on native Windows.
Two new entries are added for truncating a file and creating a sparse
file, both of which not being supported through msvcrt.dll.
The MS_* flags originated from system constants. However the flags
passed to ntfs_mount were really unrelated to the system constants and
many new MS_* flags had to be introduced as different features were
added to the library. Those flags had no counterparts in any system
APIs, so using the same naming scheme is inappropriate.
Instead, let's namespace these flags similarly to what has already been
done in ntfsprogs/libntfs earlier. This avoids any possible conflicts
with system constants.
The values of the flags themselves are kept the same as earlier, so
backward compatibility is retained.
- Replaced 'ntfschar*' parameters with 'const ntfschar*' where
appropriate (the function does not need to modify the string).
- Replaced some instances of 'u8*' and 'char*' read-only buffer
arguments with 'const u8*' and 'const char*'.
Replace the obsolete definition of reparse tags in layout.h by the
current definitions from msdn, and use them in reparse.c instead of
redefining them.
As the path passed to ntfs-3g for getxattr(2)/setxattr(2) are not
guaranteed to be the one mentioned by the caller when there are hard links,
getting/setting DOS names have to be discontinued in that situation.
Getting/setting DOS names is still possible when there is a single
non-DOS name.
Windows 8 includes a "fast restart" feature for restarting without fully
remounting the internal volumes. When this mode is selected, metadata
stored in the cache (probably hiberfil.sys) is used instead of what
is actually on disk, and this may lead to inconsistencies when changes
have been made by ntfs-3g in the meantime.
This patch tries to prevent ntfs-3g from mounting in read-write mode
when a fast restart of Windows 8 is detected. It relies on the restart
pages in the $LogFile being identified as version 2.0, which is
apparently related to data being cached for hibernation or fast restarting.
External devices, such as USB keys, may have a switch to make them
temporarily unwriteable. When such a device is plugged in, mount it
as read-only by default.
In the $LogFile, Windows 8 defines restart pages with version 2.0.
The checks designed for version 1.1 appear to apply, so accept v 2.0
and apply the usual checks.
Accept security descriptors in which the SACL is present though it does not
contain any ACE. Such security descriptors have been found in Windows
installation files.
The type of special files (symlinks, fifos, etc.) was not returned in
readdir() and they appeared wrongly in the field d_type of "struct dirent".
This prevented some applications which relied on d_type (which does
not exist in Solaris) from navigating in an NTFS tree.
Appending data to a file is done in two steps : first extending the
file to the required size, then inserting data in the created space.
There is no need to recompute the runlist at the end of the first
step, just be sure the original configuration is rolled back if inserting
data leads to an error.
When the target of a junction or a Windows-type symlink references another
junction or symlink, the search for the full path on the current partition
and its translation for case-sensitive access is interrupted. The target can
now be dereferenced, provided the end of the path needed no translation.
So far the set-group-id flag could be set in a chmod. This patch enables
the inheritance of the group to files and subdirectories, and the
inheritance of the set-group-id flag to subdirectories.
The suggestion to use option remove_hiberfile was displayed in the
standard help and when a volume is found dirty. As this option may
lead to loss of data, only mention it in the manual, with a proper
warning.
Under some conditions, Windows defines an ACL inheritance for an
unidentified authenticated user. With this patch, such an unidentified
user is treated as any user (same as "world").
When the hide_dot_files option is set, a file is marked hidden if the
first character in its name is a dot. This patch updates the hidden flag
when the file is renamed or hard linked (useful for text editors which
create files with a temporary name)
When a file is deleted, there is no need to remove its last name in
the deleted MFT record. The name may be useful for undeleting the file
later (Windows also does not delete the name).
Checking supplementary groups permissions to access a file relies on
a supplementary group list available in /proc/PID. This patch adds a
variant to implement the checks based on the specific format used
by OpenIndiana.
On Windows XP and Vista, the system hibernation is identified by the
sequence "hibr" at the beginning of hiberfil.sys. This had been changed
to "HIBR" in Windows 7, so both sequences have to be accepted as
hibernation criteria.
When the cluster size is bigger than the index block size, the index
block size unit is 512 (not the sector size) instead of the cluster size.
The partitions formatted by mkntfs and used by ntfs-3g were not
interoperable with Windows when the cluster size is bigger than 4K
and the sector size is not 512.
When computing the runlist for the first non-resident write to an
attribute, an inconsistency was created between the attribute image
and the ntfs_attr structure, which could cause an MFT record overflow
when the first write is huge and fragmented (reported by Vito Caputo).
With the default mount options, compression of new files are now done
if the parent directory is marked for compression. The mount option
"compression" is not needed any more, but the option "nocompression"
can be used to disable compression of new files.
The default option also applies to applications using libntfs-3g with
no mount command.
Logging of fixup errors for uninitialized inodes cause unnecessary
worries and suspicion of malfunctions in ntfs-3g. This patch silences
these loggings in ntfsclone and ntfsresize which have to analyze all
inodes, including the uninitialized ones.
The label changing code in ntfslabel was cleaned up and modified to use the more
advanced functionality of libntfs-3g instead of using older custom code to
resize and create resident attributes.
The core label changing functionality was also moved into the library so it can
be reused by other programs.
When clearing a volume name in Windows, $VOLUME_NAME is set to size 0, even if
the standard $AttrDef says that the minimum size is 2.
So the definition in $AttrDef doesn't reflect actual Windows behaviour in this
particular case, and to clear volume names ourselves the way Windows does it,
we must must add a special rule to permit us to truncate the $VOLUME_NAME
attribute to 0 even when $AttrDef specifies a higher value as minimum size.
When an attribute is truncated and made resident, the NAttrFullyMapped
flags has to be cleared, otherwise the attribute cannot be properly
mapped when the attribute is later made non-resident again.
When getting extents of MFT, we must be sure they are in the MFT part which
has already been mapped, otherwise we fall into an endless recursion.
Situations have been met where extents locations are described in themselves,
as a consequence of a bug, probably unrelated to ntfs-3g.
This is a severe error which chkdsk cannot fix.