Commit 86a44e90 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull ntfs3 fixes from Konstantin Komarov:
 "Use the new api for mounting as requested by Christoph.

  Also fixed:

   - some memory leaks and panic

   - xfstests (tested on x86_64) generic/016 generic/021 generic/022
     generic/041 generic/274 generic/423

   - some typos, wrong returned error codes, dead code, etc"

* tag 'ntfs3_for_5.15' of git://github.com/Paragon-Software-Group/linux-ntfs3: (70 commits)
  fs/ntfs3: Check for NULL pointers in ni_try_remove_attr_list
  fs/ntfs3: Refactor ntfs_read_mft
  fs/ntfs3: Refactor ni_parse_reparse
  fs/ntfs3: Refactor ntfs_create_inode
  fs/ntfs3: Refactor ntfs_readlink_hlp
  fs/ntfs3: Rework ntfs_utf16_to_nls
  fs/ntfs3: Fix memory leak if fill_super failed
  fs/ntfs3: Keep prealloc for all types of files
  fs/ntfs3: Remove unnecessary functions
  fs/ntfs3: Forbid FALLOC_FL_PUNCH_HOLE for normal files
  fs/ntfs3: Refactoring of ntfs_set_ea
  fs/ntfs3: Remove locked argument in ntfs_set_ea
  fs/ntfs3: Use available posix_acl_release instead of ntfs_posix_acl_release
  fs/ntfs3: Check for NULL if ATTR_EA_INFO is incorrect
  fs/ntfs3: Refactoring of ntfs_init_from_boot
  fs/ntfs3: Reject mount if boot's cluster size < media sector size
  fs/ntfs3: Refactoring lock in ntfs_init_acl
  fs/ntfs3: Change posix_acl_equiv_mode to posix_acl_update_mode
  fs/ntfs3: Pass flags to ntfs_set_ea in ntfs_set_acl_ex
  fs/ntfs3: Refactor ntfs_get_acl_ex for better readability
  ...
parents ec681c53 8607954c
Loading
Loading
Loading
Loading
+75 −66
Original line number Diff line number Diff line
@@ -4,103 +4,112 @@
NTFS3
=====


Summary and Features
====================

NTFS3 is fully functional NTFS Read-Write driver. The driver works with
NTFS versions up to 3.1, normal/compressed/sparse files
and journal replaying. File system type to use on mount is 'ntfs3'.
NTFS3 is fully functional NTFS Read-Write driver. The driver works with NTFS
versions up to 3.1. File system type to use on mount is *ntfs3*.

- This driver implements NTFS read/write support for normal, sparse and
  compressed files.
- Supports native journal replaying;
- Supports extended attributes
	Predefined extended attributes:
	- 'system.ntfs_security' gets/sets security
			descriptor (SECURITY_DESCRIPTOR_RELATIVE)
	- 'system.ntfs_attrib' gets/sets ntfs file/dir attributes.
		Note: applied to empty files, this allows to switch type between
		sparse(0x200), compressed(0x800) and normal;
- Supports native journal replaying.
- Supports NFS export of mounted NTFS volumes.
- Supports extended attributes. Predefined extended attributes:

	- *system.ntfs_security* gets/sets security

		Descriptor: SECURITY_DESCRIPTOR_RELATIVE

	- *system.ntfs_attrib* gets/sets ntfs file/dir attributes.

	  Note: Applied to empty files, this allows to switch type between
	  sparse(0x200), compressed(0x800) and normal.

Mount Options
=============

The list below describes mount options supported by NTFS3 driver in addition to
generic ones.
generic ones. You can use every mount option with **no** option. If it is in
this table marked with no it means default is without **no**.

===============================================================================
.. flat-table::
   :widths: 1 5
   :fill-cells:

nls=name		This option informs the driver how to interpret path
			strings and translate them to Unicode and back. If
			this option is not set, the default codepage will be
			used (CONFIG_NLS_DEFAULT).
			Examples:
				'nls=utf8'
   * - iocharset=name
     - This option informs the driver how to interpret path strings and
       translate them to Unicode and back. If this option is not set, the
       default codepage will be used (CONFIG_NLS_DEFAULT).

uid=
gid=
umask=			Controls the default permissions for files/directories created
			after the NTFS volume is mounted.
       Example: iocharset=utf8

fmask=
dmask=			Instead of specifying umask which applies both to
			files and directories, fmask applies only to files and
			dmask only to directories.
   * - uid=
     - :rspan:`1`
   * - gid=

nohidden		Files with the Windows-specific HIDDEN (FILE_ATTRIBUTE_HIDDEN)
			attribute will not be shown under Linux.
   * - umask=
     - Controls the default permissions for files/directories created after
       the NTFS volume is mounted.

sys_immutable		Files with the Windows-specific SYSTEM
			(FILE_ATTRIBUTE_SYSTEM) attribute will be marked as system
			immutable files.
   * - dmask=
     - :rspan:`1` Instead of specifying umask which applies both to files and
       directories, fmask applies only to files and dmask only to directories.
   * - fmask=

discard			Enable support of the TRIM command for improved performance
			on delete operations, which is recommended for use with the
			solid-state drives (SSD).
   * - noacsrules
     - "No access rules" mount option sets access rights for files/folders to
       777 and owner/group to root. This mount option absorbs all other
       permissions.

force			Forces the driver to mount partitions even if 'dirty' flag
			(volume dirty) is set. Not recommended for use.
       - Permissions change for files/folders will be reported as successful,
	 but they will remain 777.

sparse			Create new files as "sparse".
       - Owner/group change will be reported as successful, butthey will stay
	 as root.

showmeta		Use this parameter to show all meta-files (System Files) on
			a mounted NTFS partition.
			By default, all meta-files are hidden.
   * - nohidden
     - Files with the Windows-specific HIDDEN (FILE_ATTRIBUTE_HIDDEN) attribute
       will not be shown under Linux.

prealloc		Preallocate space for files excessively when file size is
			increasing on writes. Decreases fragmentation in case of
			parallel write operations to different files.
   * - sys_immutable
     - Files with the Windows-specific SYSTEM (FILE_ATTRIBUTE_SYSTEM) attribute
       will be marked as system immutable files.

no_acs_rules		"No access rules" mount option sets access rights for
			files/folders to 777 and owner/group to root. This mount
			option absorbs all other permissions:
			- permissions change for files/folders will be reported
				as successful, but they will remain 777;
			- owner/group change will be reported as successful, but
				they will stay as root
   * - discard
     - Enable support of the TRIM command for improved performance on delete
       operations, which is recommended for use with the solid-state drives
       (SSD).

acl			Support POSIX ACLs (Access Control Lists). Effective if
			supported by Kernel. Not to be confused with NTFS ACLs.
			The option specified as acl enables support for POSIX ACLs.
   * - force
     - Forces the driver to mount partitions even if volume is marked dirty.
       Not recommended for use.

noatime			All files and directories will not update their last access
			time attribute if a partition is mounted with this parameter.
			This option can speed up file system operation.
   * - sparse
     - Create new files as sparse.

===============================================================================
   * - showmeta
     - Use this parameter to show all meta-files (System Files) on a mounted
       NTFS partition. By default, all meta-files are hidden.

ToDo list
=========
   * - prealloc
     - Preallocate space for files excessively when file size is increasing on
       writes. Decreases fragmentation in case of parallel write operations to
       different files.

- Full journaling support (currently journal replaying is supported) over JBD.
   * - acl
     - Support POSIX ACLs (Access Control Lists). Effective if supported by
       Kernel. Not to be confused with NTFS ACLs. The option specified as acl
       enables support for POSIX ACLs.

Todo list
=========
- Full journaling support over JBD. Currently journal replaying is supported
  which is not necessarily as effectice as JBD would be.

References
==========
https://www.paragon-software.com/home/ntfs-linux-professional/
- Commercial version of the NTFS driver for Linux.
	https://www.paragon-software.com/home/ntfs-linux-professional/

almaz.alexandrovich@paragon-software.com
- Direct e-mail address for feedback and requests on the NTFS3 implementation.
	almaz.alexandrovich@paragon-software.com
+5 −15
Original line number Diff line number Diff line
@@ -6,13 +6,9 @@
 * TODO: Merge attr_set_size/attr_data_get_block/attr_allocate_frame?
 */

#include <linux/blkdev.h>
#include <linux/buffer_head.h>
#include <linux/fs.h>
#include <linux/hash.h>
#include <linux/nls.h>
#include <linux/ratelimit.h>
#include <linux/slab.h>
#include <linux/kernel.h>

#include "debug.h"
#include "ntfs.h"
@@ -291,7 +287,7 @@ int attr_make_nonresident(struct ntfs_inode *ni, struct ATTRIB *attr,
		if (!rsize) {
			/* Empty resident -> Non empty nonresident. */
		} else if (!is_data) {
			err = ntfs_sb_write_run(sbi, run, 0, data, rsize);
			err = ntfs_sb_write_run(sbi, run, 0, data, rsize, 0);
			if (err)
				goto out2;
		} else if (!page) {
@@ -451,11 +447,8 @@ int attr_set_size(struct ntfs_inode *ni, enum ATTR_TYPE type,
again_1:
	align = sbi->cluster_size;

	if (is_ext) {
	if (is_ext)
		align <<= attr_b->nres.c_unit;
		if (is_attr_sparsed(attr_b))
			keep_prealloc = false;
	}

	old_valid = le64_to_cpu(attr_b->nres.valid_size);
	old_size = le64_to_cpu(attr_b->nres.data_size);
@@ -465,9 +458,6 @@ int attr_set_size(struct ntfs_inode *ni, enum ATTR_TYPE type,
	new_alloc = (new_size + align - 1) & ~(u64)(align - 1);
	new_alen = new_alloc >> cluster_bits;

	if (keep_prealloc && is_ext)
		keep_prealloc = false;

	if (keep_prealloc && new_size < old_size) {
		attr_b->nres.data_size = cpu_to_le64(new_size);
		mi_b->dirty = true;
@@ -529,7 +519,7 @@ int attr_set_size(struct ntfs_inode *ni, enum ATTR_TYPE type,
		} else if (pre_alloc == -1) {
			pre_alloc = 0;
			if (type == ATTR_DATA && !name_len &&
			    sbi->options.prealloc) {
			    sbi->options->prealloc) {
				CLST new_alen2 = bytes_to_cluster(
					sbi, get_pre_allocated(new_size));
				pre_alloc = new_alen2 - new_alen;
@@ -1966,7 +1956,7 @@ int attr_punch_hole(struct ntfs_inode *ni, u64 vbo, u64 bytes, u32 *frame_size)
			return 0;

		from = vbo;
		to = (vbo + bytes) < data_size ? (vbo + bytes) : data_size;
		to = min_t(u64, vbo + bytes, data_size);
		memset(Add2Ptr(resident_data(attr_b), from), 0, to - from);
		return 0;
	}
+3 −6
Original line number Diff line number Diff line
@@ -5,10 +5,7 @@
 *
 */

#include <linux/blkdev.h>
#include <linux/buffer_head.h>
#include <linux/fs.h>
#include <linux/nls.h>

#include "debug.h"
#include "ntfs.h"
@@ -336,7 +333,7 @@ int al_add_le(struct ntfs_inode *ni, enum ATTR_TYPE type, const __le16 *name,

	if (attr && attr->non_res) {
		err = ntfs_sb_write_run(ni->mi.sbi, &al->run, 0, al->le,
					al->size);
					al->size, 0);
		if (err)
			return err;
		al->dirty = false;
@@ -423,7 +420,7 @@ bool al_delete_le(struct ntfs_inode *ni, enum ATTR_TYPE type, CLST vcn,
	return true;
}

int al_update(struct ntfs_inode *ni)
int al_update(struct ntfs_inode *ni, int sync)
{
	int err;
	struct ATTRIB *attr;
@@ -445,7 +442,7 @@ int al_update(struct ntfs_inode *ni)
		memcpy(resident_data(attr), al->le, al->size);
	} else {
		err = ntfs_sb_write_run(ni->mi.sbi, &al->run, 0, al->le,
					al->size);
					al->size, sync);
		if (err)
			goto out;

+2 −8
Original line number Diff line number Diff line
@@ -5,13 +5,8 @@
 *
 */

#include <linux/blkdev.h>
#include <linux/buffer_head.h>
#include <linux/fs.h>
#include <linux/nls.h>
#include <linux/types.h>

#include "debug.h"
#include "ntfs.h"
#include "ntfs_fs.h"

#define BITS_IN_SIZE_T (sizeof(size_t) * 8)
@@ -124,8 +119,7 @@ bool are_bits_set(const ulong *lmap, size_t bit, size_t nbits)

	pos = nbits & 7;
	if (pos) {
		u8 mask = fill_mask[pos];

		mask = fill_mask[pos];
		if ((*map & mask) != mask)
			return false;
	}
+6 −8
Original line number Diff line number Diff line
@@ -10,12 +10,10 @@
 *
 */

#include <linux/blkdev.h>
#include <linux/buffer_head.h>
#include <linux/fs.h>
#include <linux/nls.h>
#include <linux/kernel.h>

#include "debug.h"
#include "ntfs.h"
#include "ntfs_fs.h"

@@ -435,7 +433,7 @@ static void wnd_remove_free_ext(struct wnd_bitmap *wnd, size_t bit, size_t len)
		;
	} else {
		n3 = rb_next(&e->count.node);
		max_new_len = len > new_len ? len : new_len;
		max_new_len = max(len, new_len);
		if (!n3) {
			wnd->extent_max = max_new_len;
		} else {
@@ -731,7 +729,7 @@ int wnd_set_free(struct wnd_bitmap *wnd, size_t bit, size_t bits)
			wbits = wnd->bits_last;

		tail = wbits - wbit;
		op = tail < bits ? tail : bits;
		op = min_t(u32, tail, bits);

		bh = wnd_map(wnd, iw);
		if (IS_ERR(bh)) {
@@ -784,7 +782,7 @@ int wnd_set_used(struct wnd_bitmap *wnd, size_t bit, size_t bits)
			wbits = wnd->bits_last;

		tail = wbits - wbit;
		op = tail < bits ? tail : bits;
		op = min_t(u32, tail, bits);

		bh = wnd_map(wnd, iw);
		if (IS_ERR(bh)) {
@@ -834,7 +832,7 @@ static bool wnd_is_free_hlp(struct wnd_bitmap *wnd, size_t bit, size_t bits)
			wbits = wnd->bits_last;

		tail = wbits - wbit;
		op = tail < bits ? tail : bits;
		op = min_t(u32, tail, bits);

		if (wbits != wnd->free_bits[iw]) {
			bool ret;
@@ -926,7 +924,7 @@ bool wnd_is_used(struct wnd_bitmap *wnd, size_t bit, size_t bits)
			wbits = wnd->bits_last;

		tail = wbits - wbit;
		op = tail < bits ? tail : bits;
		op = min_t(u32, tail, bits);

		if (wnd->free_bits[iw]) {
			bool ret;
Loading