xref: /openbmc/linux/fs/ntfs3/ntfs_fs.h (revision 706cc802)
14534a70bSKonstantin Komarov /* SPDX-License-Identifier: GPL-2.0 */
24534a70bSKonstantin Komarov /*
34534a70bSKonstantin Komarov  *
44534a70bSKonstantin Komarov  * Copyright (C) 2019-2021 Paragon Software GmbH, All rights reserved.
54534a70bSKonstantin Komarov  *
64534a70bSKonstantin Komarov  */
74534a70bSKonstantin Komarov 
84534a70bSKonstantin Komarov // clang-format off
987790b65SKari Argillander #ifndef _LINUX_NTFS3_NTFS_FS_H
1087790b65SKari Argillander #define _LINUX_NTFS3_NTFS_FS_H
1187790b65SKari Argillander 
12f239b3a9SKari Argillander #include <linux/blkdev.h>
13f239b3a9SKari Argillander #include <linux/buffer_head.h>
14f239b3a9SKari Argillander #include <linux/fs.h>
15f239b3a9SKari Argillander #include <linux/highmem.h>
16f239b3a9SKari Argillander #include <linux/kernel.h>
17f239b3a9SKari Argillander #include <linux/mm.h>
18f239b3a9SKari Argillander #include <linux/mutex.h>
19f239b3a9SKari Argillander #include <linux/page-flags.h>
20f239b3a9SKari Argillander #include <linux/pagemap.h>
21f239b3a9SKari Argillander #include <linux/rbtree.h>
22f239b3a9SKari Argillander #include <linux/rwsem.h>
23f239b3a9SKari Argillander #include <linux/slab.h>
24f239b3a9SKari Argillander #include <linux/string.h>
25f239b3a9SKari Argillander #include <linux/time64.h>
26f239b3a9SKari Argillander #include <linux/types.h>
27f239b3a9SKari Argillander #include <linux/uidgid.h>
28f239b3a9SKari Argillander #include <asm/div64.h>
29f239b3a9SKari Argillander #include <asm/page.h>
30f239b3a9SKari Argillander 
31f239b3a9SKari Argillander #include "debug.h"
32f239b3a9SKari Argillander #include "ntfs.h"
33f239b3a9SKari Argillander 
34f239b3a9SKari Argillander struct dentry;
35f239b3a9SKari Argillander struct fiemap_extent_info;
36f239b3a9SKari Argillander struct user_namespace;
37f239b3a9SKari Argillander struct page;
38f239b3a9SKari Argillander struct writeback_control;
39f239b3a9SKari Argillander enum utf16_endian;
40f239b3a9SKari Argillander 
41f239b3a9SKari Argillander 
424534a70bSKonstantin Komarov #define MINUS_ONE_T			((size_t)(-1))
434534a70bSKonstantin Komarov /* Biggest MFT / smallest cluster */
444534a70bSKonstantin Komarov #define MAXIMUM_BYTES_PER_MFT		4096
4591a4b1eeSKonstantin Komarov #define MAXIMUM_SHIFT_BYTES_PER_MFT	12
464534a70bSKonstantin Komarov #define NTFS_BLOCKS_PER_MFT_RECORD	(MAXIMUM_BYTES_PER_MFT / 512)
474534a70bSKonstantin Komarov 
484534a70bSKonstantin Komarov #define MAXIMUM_BYTES_PER_INDEX		4096
4991a4b1eeSKonstantin Komarov #define MAXIMUM_SHIFT_BYTES_PER_INDEX	12
504534a70bSKonstantin Komarov #define NTFS_BLOCKS_PER_INODE		(MAXIMUM_BYTES_PER_INDEX / 512)
514534a70bSKonstantin Komarov 
52e8b8e97fSKari Argillander /* NTFS specific error code when fixup failed. */
534534a70bSKonstantin Komarov #define E_NTFS_FIXUP			555
54e8b8e97fSKari Argillander /* NTFS specific error code about resident->nonresident. */
554534a70bSKonstantin Komarov #define E_NTFS_NONRESIDENT		556
56e8b8e97fSKari Argillander /* NTFS specific error code about punch hole. */
574534a70bSKonstantin Komarov #define E_NTFS_NOTALIGNED		557
58e0f363a9SKonstantin Komarov /* NTFS specific error code when on-disk struct is corrupted. */
59e0f363a9SKonstantin Komarov #define E_NTFS_CORRUPT			558
604534a70bSKonstantin Komarov 
614534a70bSKonstantin Komarov 
624534a70bSKonstantin Komarov /* sbi->flags */
634534a70bSKonstantin Komarov #define NTFS_FLAGS_NODISCARD		0x00000001
64f73f9397SKonstantin Komarov /* ntfs in shutdown state. */
65323b0ab3SKonstantin Komarov #define NTFS_FLAGS_SHUTDOWN_BIT		0x00000002  /* == 4*/
66e8b8e97fSKari Argillander /* Set when LogFile is replaying. */
674534a70bSKonstantin Komarov #define NTFS_FLAGS_LOG_REPLAYING	0x00000008
68e8b8e97fSKari Argillander /* Set when we changed first MFT's which copy must be updated in $MftMirr. */
694534a70bSKonstantin Komarov #define NTFS_FLAGS_MFTMIRR		0x00001000
704534a70bSKonstantin Komarov #define NTFS_FLAGS_NEED_REPLAY		0x04000000
714534a70bSKonstantin Komarov 
724534a70bSKonstantin Komarov 
734534a70bSKonstantin Komarov /* ni->ni_flags */
744534a70bSKonstantin Komarov /*
75e8b8e97fSKari Argillander  * Data attribute is external compressed (LZX/Xpress)
764534a70bSKonstantin Komarov  * 1 - WOF_COMPRESSION_XPRESS4K
774534a70bSKonstantin Komarov  * 2 - WOF_COMPRESSION_XPRESS8K
784534a70bSKonstantin Komarov  * 3 - WOF_COMPRESSION_XPRESS16K
794534a70bSKonstantin Komarov  * 4 - WOF_COMPRESSION_LZX32K
804534a70bSKonstantin Komarov  */
814534a70bSKonstantin Komarov #define NI_FLAG_COMPRESSED_MASK		0x0000000f
82e8b8e97fSKari Argillander /* Data attribute is deduplicated. */
834534a70bSKonstantin Komarov #define NI_FLAG_DEDUPLICATED		0x00000010
844534a70bSKonstantin Komarov #define NI_FLAG_EA			0x00000020
854534a70bSKonstantin Komarov #define NI_FLAG_DIR			0x00000040
864534a70bSKonstantin Komarov #define NI_FLAG_RESIDENT		0x00000080
874534a70bSKonstantin Komarov #define NI_FLAG_UPDATE_PARENT		0x00000100
884534a70bSKonstantin Komarov // clang-format on
894534a70bSKonstantin Komarov 
904534a70bSKonstantin Komarov struct ntfs_mount_options {
91610f8f5aSKari Argillander 	char *nls_name;
924534a70bSKonstantin Komarov 	struct nls_table *nls;
934534a70bSKonstantin Komarov 
944534a70bSKonstantin Komarov 	kuid_t fs_uid;
954534a70bSKonstantin Komarov 	kgid_t fs_gid;
964534a70bSKonstantin Komarov 	u16 fs_fmask_inv;
974534a70bSKonstantin Komarov 	u16 fs_dmask_inv;
984534a70bSKonstantin Komarov 
9915b2ae77SKari Argillander 	unsigned fmask : 1; /* fmask was set. */
10015b2ae77SKari Argillander 	unsigned dmask : 1; /*dmask was set. */
10115b2ae77SKari Argillander 	unsigned sys_immutable : 1; /* Immutable system files. */
10215b2ae77SKari Argillander 	unsigned discard : 1; /* Issue discard requests on deletions. */
10315b2ae77SKari Argillander 	unsigned sparse : 1; /* Create sparse files. */
10415b2ae77SKari Argillander 	unsigned showmeta : 1; /* Show meta files. */
10515b2ae77SKari Argillander 	unsigned nohidden : 1; /* Do not show hidden files. */
106098250dbSKonstantin Komarov 	unsigned hide_dot_files : 1; /* Set hidden flag on dot files. */
1071d07a9dfSDaniel Pinto 	unsigned windows_names : 1; /* Disallow names forbidden by Windows. */
10815b2ae77SKari Argillander 	unsigned force : 1; /* RW mount dirty volume. */
10915b2ae77SKari Argillander 	unsigned prealloc : 1; /* Preallocate space when file is growing. */
110a3a956c7SKonstantin Komarov 	unsigned nocase : 1; /* case insensitive. */
1114534a70bSKonstantin Komarov };
1124534a70bSKonstantin Komarov 
113e8b8e97fSKari Argillander /* Special value to unpack and deallocate. */
1144534a70bSKonstantin Komarov #define RUN_DEALLOCATE ((struct runs_tree *)(size_t)1)
1154534a70bSKonstantin Komarov 
116e8b8e97fSKari Argillander /* TODO: Use rb tree instead of array. */
1174534a70bSKonstantin Komarov struct runs_tree {
1184534a70bSKonstantin Komarov 	struct ntfs_run *runs;
119e8b8e97fSKari Argillander 	size_t count; /* Currently used size a ntfs_run storage. */
120e8b8e97fSKari Argillander 	size_t allocated; /* Currently allocated ntfs_run storage size. */
1214534a70bSKonstantin Komarov };
1224534a70bSKonstantin Komarov 
1234534a70bSKonstantin Komarov struct ntfs_buffers {
1244534a70bSKonstantin Komarov 	/* Biggest MFT / smallest cluster = 4096 / 512 = 8 */
1254534a70bSKonstantin Komarov 	/* Biggest index / smallest cluster = 4096 / 512 = 8 */
1264534a70bSKonstantin Komarov 	struct buffer_head *bh[PAGE_SIZE >> SECTOR_SHIFT];
1274534a70bSKonstantin Komarov 	u32 bytes;
1284534a70bSKonstantin Komarov 	u32 nbufs;
1294534a70bSKonstantin Komarov 	u32 off;
1304534a70bSKonstantin Komarov };
1314534a70bSKonstantin Komarov 
1324534a70bSKonstantin Komarov enum ALLOCATE_OPT {
133e8b8e97fSKari Argillander 	ALLOCATE_DEF = 0, // Allocate all clusters.
134e8b8e97fSKari Argillander 	ALLOCATE_MFT = 1, // Allocate for MFT.
135c380b52fSKonstantin Komarov 	ALLOCATE_ZERO = 2, // Zeroout new allocated clusters
1364534a70bSKonstantin Komarov };
1374534a70bSKonstantin Komarov 
1384534a70bSKonstantin Komarov enum bitmap_mutex_classes {
1394534a70bSKonstantin Komarov 	BITMAP_MUTEX_CLUSTERS = 0,
1404534a70bSKonstantin Komarov 	BITMAP_MUTEX_MFT = 1,
1414534a70bSKonstantin Komarov };
1424534a70bSKonstantin Komarov 
1434534a70bSKonstantin Komarov struct wnd_bitmap {
1444534a70bSKonstantin Komarov 	struct super_block *sb;
1454534a70bSKonstantin Komarov 	struct rw_semaphore rw_lock;
1464534a70bSKonstantin Komarov 
1474534a70bSKonstantin Komarov 	struct runs_tree run;
1484534a70bSKonstantin Komarov 	size_t nbits;
1494534a70bSKonstantin Komarov 
150e8b8e97fSKari Argillander 	size_t total_zeroes; // Total number of free bits.
151e8b8e97fSKari Argillander 	u16 *free_bits; // Free bits in each window.
1524534a70bSKonstantin Komarov 	size_t nwnd;
153e8b8e97fSKari Argillander 	u32 bits_last; // Bits in last window.
1544534a70bSKonstantin Komarov 
155e8b8e97fSKari Argillander 	struct rb_root start_tree; // Extents, sorted by 'start'.
156e8b8e97fSKari Argillander 	struct rb_root count_tree; // Extents, sorted by 'count + start'.
157e8b8e97fSKari Argillander 	size_t count; // Extents count.
1584534a70bSKonstantin Komarov 
1594534a70bSKonstantin Komarov 	/*
160e8b8e97fSKari Argillander 	 * -1 Tree is activated but not updated (too many fragments).
161e8b8e97fSKari Argillander 	 * 0 - Tree is not activated.
162e8b8e97fSKari Argillander 	 * 1 - Tree is activated and updated.
1634534a70bSKonstantin Komarov 	 */
1644534a70bSKonstantin Komarov 	int uptodated;
165e8b8e97fSKari Argillander 	size_t extent_min; // Minimal extent used while building.
166e8b8e97fSKari Argillander 	size_t extent_max; // Upper estimate of biggest free block.
1674534a70bSKonstantin Komarov 
1684534a70bSKonstantin Komarov 	/* Zone [bit, end) */
1694534a70bSKonstantin Komarov 	size_t zone_bit;
1704534a70bSKonstantin Komarov 	size_t zone_end;
1714534a70bSKonstantin Komarov 
1724534a70bSKonstantin Komarov 	bool inited;
1734534a70bSKonstantin Komarov };
1744534a70bSKonstantin Komarov 
1754534a70bSKonstantin Komarov typedef int (*NTFS_CMP_FUNC)(const void *key1, size_t len1, const void *key2,
1764534a70bSKonstantin Komarov 			     size_t len2, const void *param);
1774534a70bSKonstantin Komarov 
1784534a70bSKonstantin Komarov enum index_mutex_classed {
1794534a70bSKonstantin Komarov 	INDEX_MUTEX_I30 = 0,
1804534a70bSKonstantin Komarov 	INDEX_MUTEX_SII = 1,
1814534a70bSKonstantin Komarov 	INDEX_MUTEX_SDH = 2,
1824534a70bSKonstantin Komarov 	INDEX_MUTEX_SO = 3,
1834534a70bSKonstantin Komarov 	INDEX_MUTEX_SQ = 4,
1844534a70bSKonstantin Komarov 	INDEX_MUTEX_SR = 5,
1854534a70bSKonstantin Komarov 	INDEX_MUTEX_TOTAL
1864534a70bSKonstantin Komarov };
1874534a70bSKonstantin Komarov 
188e8b8e97fSKari Argillander /* ntfs_index - Allocation unit inside directory. */
1894534a70bSKonstantin Komarov struct ntfs_index {
1904534a70bSKonstantin Komarov 	struct runs_tree bitmap_run;
1914534a70bSKonstantin Komarov 	struct runs_tree alloc_run;
1924534a70bSKonstantin Komarov 	/* read/write access to 'bitmap_run'/'alloc_run' while ntfs_readdir */
1934534a70bSKonstantin Komarov 	struct rw_semaphore run_lock;
1944534a70bSKonstantin Komarov 
195e8b8e97fSKari Argillander 	/*TODO: Remove 'cmp'. */
1964534a70bSKonstantin Komarov 	NTFS_CMP_FUNC cmp;
1974534a70bSKonstantin Komarov 
1984534a70bSKonstantin Komarov 	u8 index_bits; // log2(root->index_block_size)
1994534a70bSKonstantin Komarov 	u8 idx2vbn_bits; // log2(root->index_block_clst)
2004534a70bSKonstantin Komarov 	u8 vbn2vbo_bits; // index_block_size < cluster? 9 : cluster_bits
2014534a70bSKonstantin Komarov 	u8 type; // index_mutex_classed
2024534a70bSKonstantin Komarov };
2034534a70bSKonstantin Komarov 
204e8b8e97fSKari Argillander /* Minimum MFT zone. */
2054534a70bSKonstantin Komarov #define NTFS_MIN_MFT_ZONE 100
20697a6815eSKonstantin Komarov /* Step to increase the MFT. */
20797a6815eSKonstantin Komarov #define NTFS_MFT_INCREASE_STEP 1024
2084534a70bSKonstantin Komarov 
209e8b8e97fSKari Argillander /* Ntfs file system in-core superblock data. */
2104534a70bSKonstantin Komarov struct ntfs_sb_info {
2114534a70bSKonstantin Komarov 	struct super_block *sb;
2124534a70bSKonstantin Komarov 
2134534a70bSKonstantin Komarov 	u32 discard_granularity;
2144534a70bSKonstantin Komarov 	u64 discard_granularity_mask_inv; // ~(discard_granularity_mask_inv-1)
2154534a70bSKonstantin Komarov 
2164534a70bSKonstantin Komarov 	u32 cluster_size; // bytes per cluster
2174534a70bSKonstantin Komarov 	u32 cluster_mask; // == cluster_size - 1
2184534a70bSKonstantin Komarov 	u64 cluster_mask_inv; // ~(cluster_size - 1)
2194534a70bSKonstantin Komarov 	u32 block_mask; // sb->s_blocksize - 1
2204534a70bSKonstantin Komarov 	u32 blocks_per_cluster; // cluster_size / sb->s_blocksize
2214534a70bSKonstantin Komarov 
2224534a70bSKonstantin Komarov 	u32 record_size;
2234534a70bSKonstantin Komarov 	u32 index_size;
2244534a70bSKonstantin Komarov 
2254534a70bSKonstantin Komarov 	u8 cluster_bits;
2264534a70bSKonstantin Komarov 	u8 record_bits;
2274534a70bSKonstantin Komarov 
228e8b8e97fSKari Argillander 	u64 maxbytes; // Maximum size for normal files.
229e8b8e97fSKari Argillander 	u64 maxbytes_sparse; // Maximum size for sparse file.
2304534a70bSKonstantin Komarov 
231f73f9397SKonstantin Komarov 	unsigned long flags; // See NTFS_FLAGS_
2324534a70bSKonstantin Komarov 
2338335ebe1SKonstantin Komarov 	CLST zone_max; // Maximum MFT zone length in clusters
234e8b8e97fSKari Argillander 	CLST bad_clusters; // The count of marked bad clusters.
2354534a70bSKonstantin Komarov 
236e8b8e97fSKari Argillander 	u16 max_bytes_per_attr; // Maximum attribute size in record.
237e8b8e97fSKari Argillander 	u16 attr_size_tr; // Attribute size threshold (320 bytes).
2384534a70bSKonstantin Komarov 
239e8b8e97fSKari Argillander 	/* Records in $Extend. */
2404534a70bSKonstantin Komarov 	CLST objid_no;
2414534a70bSKonstantin Komarov 	CLST quota_no;
2424534a70bSKonstantin Komarov 	CLST reparse_no;
2434534a70bSKonstantin Komarov 	CLST usn_jrnl_no;
2444534a70bSKonstantin Komarov 
245e8b8e97fSKari Argillander 	struct ATTR_DEF_ENTRY *def_table; // Attribute definition table.
2464534a70bSKonstantin Komarov 	u32 def_entries;
2474534a70bSKonstantin Komarov 	u32 ea_max_size;
2484534a70bSKonstantin Komarov 
2494534a70bSKonstantin Komarov 	struct MFT_REC *new_rec;
2504534a70bSKonstantin Komarov 
2514534a70bSKonstantin Komarov 	u16 *upcase;
2524534a70bSKonstantin Komarov 
2534534a70bSKonstantin Komarov 	struct {
2544534a70bSKonstantin Komarov 		u64 lbo, lbo2;
2554534a70bSKonstantin Komarov 		struct ntfs_inode *ni;
2564534a70bSKonstantin Komarov 		struct wnd_bitmap bitmap; // $MFT::Bitmap
2574534a70bSKonstantin Komarov 		/*
258e8b8e97fSKari Argillander 		 * MFT records [11-24) used to expand MFT itself.
2594534a70bSKonstantin Komarov 		 * They always marked as used in $MFT::Bitmap
260e8b8e97fSKari Argillander 		 * 'reserved_bitmap' contains real bitmap of these records.
2614534a70bSKonstantin Komarov 		 */
262e8b8e97fSKari Argillander 		ulong reserved_bitmap; // Bitmap of used records [11 - 24)
2634534a70bSKonstantin Komarov 		size_t next_free; // The next record to allocate from
264e8b8e97fSKari Argillander 		size_t used; // MFT valid size in records.
2654534a70bSKonstantin Komarov 		u32 recs_mirr; // Number of records in MFTMirr
2664534a70bSKonstantin Komarov 		u8 next_reserved;
2674534a70bSKonstantin Komarov 		u8 reserved_bitmap_inited;
2684534a70bSKonstantin Komarov 	} mft;
2694534a70bSKonstantin Komarov 
2704534a70bSKonstantin Komarov 	struct {
2714534a70bSKonstantin Komarov 		struct wnd_bitmap bitmap; // $Bitmap::Data
2724534a70bSKonstantin Komarov 		CLST next_free_lcn;
2734534a70bSKonstantin Komarov 	} used;
2744534a70bSKonstantin Komarov 
2754534a70bSKonstantin Komarov 	struct {
276e8b8e97fSKari Argillander 		u64 size; // In bytes.
277e8b8e97fSKari Argillander 		u64 blocks; // In blocks.
2784534a70bSKonstantin Komarov 		u64 ser_num;
2794534a70bSKonstantin Komarov 		struct ntfs_inode *ni;
280e8b8e97fSKari Argillander 		__le16 flags; // Cached current VOLUME_INFO::flags, VOLUME_FLAG_DIRTY.
2814534a70bSKonstantin Komarov 		u8 major_ver;
2824534a70bSKonstantin Komarov 		u8 minor_ver;
2837832e123SKonstantin Komarov 		char label[256];
284e8b8e97fSKari Argillander 		bool real_dirty; // Real fs state.
2854534a70bSKonstantin Komarov 	} volume;
2864534a70bSKonstantin Komarov 
2874534a70bSKonstantin Komarov 	struct {
2884534a70bSKonstantin Komarov 		struct ntfs_index index_sii;
2894534a70bSKonstantin Komarov 		struct ntfs_index index_sdh;
2904534a70bSKonstantin Komarov 		struct ntfs_inode *ni;
2914534a70bSKonstantin Komarov 		u32 next_id;
2924534a70bSKonstantin Komarov 		u64 next_off;
2934534a70bSKonstantin Komarov 		__le32 def_security_id;
2944534a70bSKonstantin Komarov 	} security;
2954534a70bSKonstantin Komarov 
2964534a70bSKonstantin Komarov 	struct {
2974534a70bSKonstantin Komarov 		struct ntfs_index index_r;
2984534a70bSKonstantin Komarov 		struct ntfs_inode *ni;
2994534a70bSKonstantin Komarov 		u64 max_size; // 16K
3004534a70bSKonstantin Komarov 	} reparse;
3014534a70bSKonstantin Komarov 
3024534a70bSKonstantin Komarov 	struct {
3034534a70bSKonstantin Komarov 		struct ntfs_index index_o;
3044534a70bSKonstantin Komarov 		struct ntfs_inode *ni;
3054534a70bSKonstantin Komarov 	} objid;
3064534a70bSKonstantin Komarov 
3074534a70bSKonstantin Komarov 	struct {
3084534a70bSKonstantin Komarov 		struct mutex mtx_lznt;
3094534a70bSKonstantin Komarov 		struct lznt *lznt;
3104534a70bSKonstantin Komarov #ifdef CONFIG_NTFS3_LZX_XPRESS
3114534a70bSKonstantin Komarov 		struct mutex mtx_xpress;
3124534a70bSKonstantin Komarov 		struct xpress_decompressor *xpress;
3134534a70bSKonstantin Komarov 		struct mutex mtx_lzx;
3144534a70bSKonstantin Komarov 		struct lzx_decompressor *lzx;
3154534a70bSKonstantin Komarov #endif
3164534a70bSKonstantin Komarov 	} compress;
3174534a70bSKonstantin Komarov 
318564c97bdSKari Argillander 	struct ntfs_mount_options *options;
3194534a70bSKonstantin Komarov 	struct ratelimit_state msg_ratelimit;
3207832e123SKonstantin Komarov 	struct proc_dir_entry *procdir;
3214534a70bSKonstantin Komarov };
3224534a70bSKonstantin Komarov 
323e8b8e97fSKari Argillander /* One MFT record(usually 1024 bytes), consists of attributes. */
3244534a70bSKonstantin Komarov struct mft_inode {
3254534a70bSKonstantin Komarov 	struct rb_node node;
3264534a70bSKonstantin Komarov 	struct ntfs_sb_info *sbi;
3274534a70bSKonstantin Komarov 
3284534a70bSKonstantin Komarov 	struct MFT_REC *mrec;
3294534a70bSKonstantin Komarov 	struct ntfs_buffers nb;
3304534a70bSKonstantin Komarov 
3314534a70bSKonstantin Komarov 	CLST rno;
3324534a70bSKonstantin Komarov 	bool dirty;
3334534a70bSKonstantin Komarov };
3344534a70bSKonstantin Komarov 
335e8b8e97fSKari Argillander /* Nested class for ntfs_inode::ni_lock. */
3364534a70bSKonstantin Komarov enum ntfs_inode_mutex_lock_class {
3374534a70bSKonstantin Komarov 	NTFS_INODE_MUTEX_DIRTY,
3384534a70bSKonstantin Komarov 	NTFS_INODE_MUTEX_SECURITY,
3394534a70bSKonstantin Komarov 	NTFS_INODE_MUTEX_OBJID,
3404534a70bSKonstantin Komarov 	NTFS_INODE_MUTEX_REPARSE,
3414534a70bSKonstantin Komarov 	NTFS_INODE_MUTEX_NORMAL,
3424534a70bSKonstantin Komarov 	NTFS_INODE_MUTEX_PARENT,
3430ad9dfcbSKonstantin Komarov 	NTFS_INODE_MUTEX_PARENT2,
3444534a70bSKonstantin Komarov };
3454534a70bSKonstantin Komarov 
3464534a70bSKonstantin Komarov /*
34796de65a9SKonstantin Komarov  * struct ntfs_inode
348e8b8e97fSKari Argillander  *
349e8b8e97fSKari Argillander  * Ntfs inode - extends linux inode. consists of one or more MFT inodes.
3504534a70bSKonstantin Komarov  */
3514534a70bSKonstantin Komarov struct ntfs_inode {
3524534a70bSKonstantin Komarov 	struct mft_inode mi; // base record
3534534a70bSKonstantin Komarov 
3544534a70bSKonstantin Komarov 	/*
355e8b8e97fSKari Argillander 	 * Valid size: [0 - i_valid) - these range in file contains valid data.
356e8b8e97fSKari Argillander 	 * Range [i_valid - inode->i_size) - contains 0.
357e8b8e97fSKari Argillander 	 * Usually i_valid <= inode->i_size.
3584534a70bSKonstantin Komarov 	 */
3594534a70bSKonstantin Komarov 	u64 i_valid;
3604534a70bSKonstantin Komarov 	struct timespec64 i_crtime;
3614534a70bSKonstantin Komarov 
3624534a70bSKonstantin Komarov 	struct mutex ni_lock;
3634534a70bSKonstantin Komarov 
364e8b8e97fSKari Argillander 	/* File attributes from std. */
3654534a70bSKonstantin Komarov 	enum FILE_ATTRIBUTE std_fa;
3664534a70bSKonstantin Komarov 	__le32 std_security_id;
3674534a70bSKonstantin Komarov 
3684534a70bSKonstantin Komarov 	/*
369e8b8e97fSKari Argillander 	 * Tree of mft_inode.
370e8b8e97fSKari Argillander 	 * Not empty when primary MFT record (usually 1024 bytes) can't save all attributes
371e8b8e97fSKari Argillander 	 * e.g. file becomes too fragmented or contains a lot of names.
3724534a70bSKonstantin Komarov 	 */
3734534a70bSKonstantin Komarov 	struct rb_root mi_tree;
3744534a70bSKonstantin Komarov 
3754534a70bSKonstantin Komarov 	/*
3764534a70bSKonstantin Komarov 	 * This member is used in ntfs_readdir to ensure that all subrecords are loaded
3774534a70bSKonstantin Komarov 	 */
3784534a70bSKonstantin Komarov 	u8 mi_loaded;
3794534a70bSKonstantin Komarov 
3804534a70bSKonstantin Komarov 	union {
3814534a70bSKonstantin Komarov 		struct ntfs_index dir;
3824534a70bSKonstantin Komarov 		struct {
3834534a70bSKonstantin Komarov 			struct rw_semaphore run_lock;
3844534a70bSKonstantin Komarov 			struct runs_tree run;
3854534a70bSKonstantin Komarov #ifdef CONFIG_NTFS3_LZX_XPRESS
3864534a70bSKonstantin Komarov 			struct page *offs_page;
3874534a70bSKonstantin Komarov #endif
3884534a70bSKonstantin Komarov 		} file;
3894534a70bSKonstantin Komarov 	};
3904534a70bSKonstantin Komarov 
3914534a70bSKonstantin Komarov 	struct {
3924534a70bSKonstantin Komarov 		struct runs_tree run;
393e8b8e97fSKari Argillander 		struct ATTR_LIST_ENTRY *le; // 1K aligned memory.
3944534a70bSKonstantin Komarov 		size_t size;
3954534a70bSKonstantin Komarov 		bool dirty;
3964534a70bSKonstantin Komarov 	} attr_list;
3974534a70bSKonstantin Komarov 
3984534a70bSKonstantin Komarov 	size_t ni_flags; // NI_FLAG_XXX
3994534a70bSKonstantin Komarov 
4004534a70bSKonstantin Komarov 	struct inode vfs_inode;
4014534a70bSKonstantin Komarov };
4024534a70bSKonstantin Komarov 
4034534a70bSKonstantin Komarov struct indx_node {
4044534a70bSKonstantin Komarov 	struct ntfs_buffers nb;
4054534a70bSKonstantin Komarov 	struct INDEX_BUFFER *index;
4064534a70bSKonstantin Komarov };
4074534a70bSKonstantin Komarov 
4084534a70bSKonstantin Komarov struct ntfs_fnd {
4094534a70bSKonstantin Komarov 	int level;
4104534a70bSKonstantin Komarov 	struct indx_node *nodes[20];
4114534a70bSKonstantin Komarov 	struct NTFS_DE *de[20];
4124534a70bSKonstantin Komarov 	struct NTFS_DE *root_de;
4134534a70bSKonstantin Komarov };
4144534a70bSKonstantin Komarov 
4154534a70bSKonstantin Komarov enum REPARSE_SIGN {
4164534a70bSKonstantin Komarov 	REPARSE_NONE = 0,
4174534a70bSKonstantin Komarov 	REPARSE_COMPRESSED = 1,
4184534a70bSKonstantin Komarov 	REPARSE_DEDUPLICATED = 2,
4194534a70bSKonstantin Komarov 	REPARSE_LINK = 3
4204534a70bSKonstantin Komarov };
4214534a70bSKonstantin Komarov 
422e8b8e97fSKari Argillander /* Functions from attrib.c */
4234534a70bSKonstantin Komarov int attr_allocate_clusters(struct ntfs_sb_info *sbi, struct runs_tree *run,
4244534a70bSKonstantin Komarov 			   CLST vcn, CLST lcn, CLST len, CLST *pre_alloc,
4254534a70bSKonstantin Komarov 			   enum ALLOCATE_OPT opt, CLST *alen, const size_t fr,
426c380b52fSKonstantin Komarov 			   CLST *new_lcn, CLST *new_len);
4274534a70bSKonstantin Komarov int attr_make_nonresident(struct ntfs_inode *ni, struct ATTRIB *attr,
4284534a70bSKonstantin Komarov 			  struct ATTR_LIST_ENTRY *le, struct mft_inode *mi,
4294534a70bSKonstantin Komarov 			  u64 new_size, struct runs_tree *run,
4304534a70bSKonstantin Komarov 			  struct ATTRIB **ins_attr, struct page *page);
4314534a70bSKonstantin Komarov int attr_set_size(struct ntfs_inode *ni, enum ATTR_TYPE type,
4324534a70bSKonstantin Komarov 		  const __le16 *name, u8 name_len, struct runs_tree *run,
4334534a70bSKonstantin Komarov 		  u64 new_size, const u64 *new_valid, bool keep_prealloc,
4344534a70bSKonstantin Komarov 		  struct ATTRIB **ret);
4354534a70bSKonstantin Komarov int attr_data_get_block(struct ntfs_inode *ni, CLST vcn, CLST clen, CLST *lcn,
436c380b52fSKonstantin Komarov 			CLST *len, bool *new, bool zero);
4374534a70bSKonstantin Komarov int attr_data_read_resident(struct ntfs_inode *ni, struct page *page);
4384534a70bSKonstantin Komarov int attr_data_write_resident(struct ntfs_inode *ni, struct page *page);
4394534a70bSKonstantin Komarov int attr_load_runs_vcn(struct ntfs_inode *ni, enum ATTR_TYPE type,
4404534a70bSKonstantin Komarov 		       const __le16 *name, u8 name_len, struct runs_tree *run,
4414534a70bSKonstantin Komarov 		       CLST vcn);
4424534a70bSKonstantin Komarov int attr_load_runs_range(struct ntfs_inode *ni, enum ATTR_TYPE type,
4434534a70bSKonstantin Komarov 			 const __le16 *name, u8 name_len, struct runs_tree *run,
4444534a70bSKonstantin Komarov 			 u64 from, u64 to);
4454534a70bSKonstantin Komarov int attr_wof_frame_info(struct ntfs_inode *ni, struct ATTRIB *attr,
4464534a70bSKonstantin Komarov 			struct runs_tree *run, u64 frame, u64 frames,
4474534a70bSKonstantin Komarov 			u8 frame_bits, u32 *ondisk_size, u64 *vbo_data);
4484534a70bSKonstantin Komarov int attr_is_frame_compressed(struct ntfs_inode *ni, struct ATTRIB *attr,
4494534a70bSKonstantin Komarov 			     CLST frame, CLST *clst_data);
4504534a70bSKonstantin Komarov int attr_allocate_frame(struct ntfs_inode *ni, CLST frame, size_t compr_size,
4514534a70bSKonstantin Komarov 			u64 new_valid);
4524534a70bSKonstantin Komarov int attr_collapse_range(struct ntfs_inode *ni, u64 vbo, u64 bytes);
453aa30eccbSKonstantin Komarov int attr_insert_range(struct ntfs_inode *ni, u64 vbo, u64 bytes);
4544534a70bSKonstantin Komarov int attr_punch_hole(struct ntfs_inode *ni, u64 vbo, u64 bytes, u32 *frame_size);
4554534a70bSKonstantin Komarov 
456e8b8e97fSKari Argillander /* Functions from attrlist.c */
4574534a70bSKonstantin Komarov void al_destroy(struct ntfs_inode *ni);
4584534a70bSKonstantin Komarov bool al_verify(struct ntfs_inode *ni);
4594534a70bSKonstantin Komarov int ntfs_load_attr_list(struct ntfs_inode *ni, struct ATTRIB *attr);
4604534a70bSKonstantin Komarov struct ATTR_LIST_ENTRY *al_enumerate(struct ntfs_inode *ni,
4614534a70bSKonstantin Komarov 				     struct ATTR_LIST_ENTRY *le);
4624534a70bSKonstantin Komarov struct ATTR_LIST_ENTRY *al_find_le(struct ntfs_inode *ni,
4634534a70bSKonstantin Komarov 				   struct ATTR_LIST_ENTRY *le,
4644534a70bSKonstantin Komarov 				   const struct ATTRIB *attr);
4654534a70bSKonstantin Komarov struct ATTR_LIST_ENTRY *al_find_ex(struct ntfs_inode *ni,
4664534a70bSKonstantin Komarov 				   struct ATTR_LIST_ENTRY *le,
4674534a70bSKonstantin Komarov 				   enum ATTR_TYPE type, const __le16 *name,
4684534a70bSKonstantin Komarov 				   u8 name_len, const CLST *vcn);
4694534a70bSKonstantin Komarov int al_add_le(struct ntfs_inode *ni, enum ATTR_TYPE type, const __le16 *name,
4704534a70bSKonstantin Komarov 	      u8 name_len, CLST svcn, __le16 id, const struct MFT_REF *ref,
4714534a70bSKonstantin Komarov 	      struct ATTR_LIST_ENTRY **new_le);
4724534a70bSKonstantin Komarov bool al_remove_le(struct ntfs_inode *ni, struct ATTR_LIST_ENTRY *le);
4734534a70bSKonstantin Komarov bool al_delete_le(struct ntfs_inode *ni, enum ATTR_TYPE type, CLST vcn,
474a81f47c4SKonstantin Komarov 		  const __le16 *name, u8 name_len, const struct MFT_REF *ref);
47563544672SKonstantin Komarov int al_update(struct ntfs_inode *ni, int sync);
al_aligned(size_t size)4764534a70bSKonstantin Komarov static inline size_t al_aligned(size_t size)
4774534a70bSKonstantin Komarov {
478fb7bcd17SDan Carpenter 	return size_add(size, 1023) & ~(size_t)1023;
4794534a70bSKonstantin Komarov }
4804534a70bSKonstantin Komarov 
481e8b8e97fSKari Argillander /* Globals from bitfunc.c */
48208811ba5SKonstantin Komarov bool are_bits_clear(const void *map, size_t bit, size_t nbits);
48308811ba5SKonstantin Komarov bool are_bits_set(const void *map, size_t bit, size_t nbits);
48408811ba5SKonstantin Komarov size_t get_set_bits_ex(const void *map, size_t bit, size_t nbits);
4854534a70bSKonstantin Komarov 
486e8b8e97fSKari Argillander /* Globals from dir.c */
4872c690788SKonstantin Komarov int ntfs_utf16_to_nls(struct ntfs_sb_info *sbi, const __le16 *name, u32 len,
4884534a70bSKonstantin Komarov 		      u8 *buf, int buf_len);
4894534a70bSKonstantin Komarov int ntfs_nls_to_utf16(struct ntfs_sb_info *sbi, const u8 *name, u32 name_len,
4904534a70bSKonstantin Komarov 		      struct cpu_str *uni, u32 max_ulen,
4914534a70bSKonstantin Komarov 		      enum utf16_endian endian);
4924534a70bSKonstantin Komarov struct inode *dir_search_u(struct inode *dir, const struct cpu_str *uni,
4934534a70bSKonstantin Komarov 			   struct ntfs_fnd *fnd);
4944534a70bSKonstantin Komarov bool dir_is_empty(struct inode *dir);
4954534a70bSKonstantin Komarov extern const struct file_operations ntfs_dir_operations;
4964534a70bSKonstantin Komarov 
497e8b8e97fSKari Argillander /* Globals from file.c */
498b74d24f7SChristian Brauner int ntfs_getattr(struct mnt_idmap *idmap, const struct path *path,
4994534a70bSKonstantin Komarov 		 struct kstat *stat, u32 request_mask, u32 flags);
500c1632a0fSChristian Brauner int ntfs3_setattr(struct mnt_idmap *idmap, struct dentry *dentry,
5014534a70bSKonstantin Komarov 		  struct iattr *attr);
5024534a70bSKonstantin Komarov int ntfs_file_open(struct inode *inode, struct file *file);
5034534a70bSKonstantin Komarov int ntfs_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
5044534a70bSKonstantin Komarov 		__u64 start, __u64 len);
5054534a70bSKonstantin Komarov extern const struct inode_operations ntfs_special_inode_operations;
5064534a70bSKonstantin Komarov extern const struct inode_operations ntfs_file_inode_operations;
5074534a70bSKonstantin Komarov extern const struct file_operations ntfs_file_operations;
5084534a70bSKonstantin Komarov 
509e8b8e97fSKari Argillander /* Globals from frecord.c */
5104534a70bSKonstantin Komarov void ni_remove_mi(struct ntfs_inode *ni, struct mft_inode *mi);
5114534a70bSKonstantin Komarov struct ATTR_STD_INFO *ni_std(struct ntfs_inode *ni);
5124534a70bSKonstantin Komarov struct ATTR_STD_INFO5 *ni_std5(struct ntfs_inode *ni);
5134534a70bSKonstantin Komarov void ni_clear(struct ntfs_inode *ni);
5144534a70bSKonstantin Komarov int ni_load_mi_ex(struct ntfs_inode *ni, CLST rno, struct mft_inode **mi);
51578ab59feSKonstantin Komarov int ni_load_mi(struct ntfs_inode *ni, const struct ATTR_LIST_ENTRY *le,
5164534a70bSKonstantin Komarov 	       struct mft_inode **mi);
5174534a70bSKonstantin Komarov struct ATTRIB *ni_find_attr(struct ntfs_inode *ni, struct ATTRIB *attr,
5184534a70bSKonstantin Komarov 			    struct ATTR_LIST_ENTRY **entry_o,
5194534a70bSKonstantin Komarov 			    enum ATTR_TYPE type, const __le16 *name,
5204534a70bSKonstantin Komarov 			    u8 name_len, const CLST *vcn,
5214534a70bSKonstantin Komarov 			    struct mft_inode **mi);
5224534a70bSKonstantin Komarov struct ATTRIB *ni_enum_attr_ex(struct ntfs_inode *ni, struct ATTRIB *attr,
5234534a70bSKonstantin Komarov 			       struct ATTR_LIST_ENTRY **le,
5244534a70bSKonstantin Komarov 			       struct mft_inode **mi);
5254534a70bSKonstantin Komarov struct ATTRIB *ni_load_attr(struct ntfs_inode *ni, enum ATTR_TYPE type,
5264534a70bSKonstantin Komarov 			    const __le16 *name, u8 name_len, CLST vcn,
5274534a70bSKonstantin Komarov 			    struct mft_inode **pmi);
5284534a70bSKonstantin Komarov int ni_load_all_mi(struct ntfs_inode *ni);
5294534a70bSKonstantin Komarov bool ni_add_subrecord(struct ntfs_inode *ni, CLST rno, struct mft_inode **mi);
5304534a70bSKonstantin Komarov int ni_remove_attr(struct ntfs_inode *ni, enum ATTR_TYPE type,
531a81f47c4SKonstantin Komarov 		   const __le16 *name, u8 name_len, bool base_only,
5324534a70bSKonstantin Komarov 		   const __le16 *id);
5334534a70bSKonstantin Komarov int ni_create_attr_list(struct ntfs_inode *ni);
5344534a70bSKonstantin Komarov int ni_expand_list(struct ntfs_inode *ni);
5354534a70bSKonstantin Komarov int ni_insert_nonresident(struct ntfs_inode *ni, enum ATTR_TYPE type,
5364534a70bSKonstantin Komarov 			  const __le16 *name, u8 name_len,
5374534a70bSKonstantin Komarov 			  const struct runs_tree *run, CLST svcn, CLST len,
5384534a70bSKonstantin Komarov 			  __le16 flags, struct ATTRIB **new_attr,
539c1e0ab37SKonstantin Komarov 			  struct mft_inode **mi, struct ATTR_LIST_ENTRY **le);
5404534a70bSKonstantin Komarov int ni_insert_resident(struct ntfs_inode *ni, u32 data_size,
5414534a70bSKonstantin Komarov 		       enum ATTR_TYPE type, const __le16 *name, u8 name_len,
54278ab59feSKonstantin Komarov 		       struct ATTRIB **new_attr, struct mft_inode **mi,
54378ab59feSKonstantin Komarov 		       struct ATTR_LIST_ENTRY **le);
54478ab59feSKonstantin Komarov void ni_remove_attr_le(struct ntfs_inode *ni, struct ATTRIB *attr,
54578ab59feSKonstantin Komarov 		       struct mft_inode *mi, struct ATTR_LIST_ENTRY *le);
5464534a70bSKonstantin Komarov int ni_delete_all(struct ntfs_inode *ni);
5474534a70bSKonstantin Komarov struct ATTR_FILE_NAME *ni_fname_name(struct ntfs_inode *ni,
548d5ca7733SKonstantin Komarov 				     const struct le_str *uni,
5494534a70bSKonstantin Komarov 				     const struct MFT_REF *home,
55078ab59feSKonstantin Komarov 				     struct mft_inode **mi,
5514534a70bSKonstantin Komarov 				     struct ATTR_LIST_ENTRY **entry);
5524534a70bSKonstantin Komarov struct ATTR_FILE_NAME *ni_fname_type(struct ntfs_inode *ni, u8 name_type,
55378ab59feSKonstantin Komarov 				     struct mft_inode **mi,
5544534a70bSKonstantin Komarov 				     struct ATTR_LIST_ENTRY **entry);
5554534a70bSKonstantin Komarov int ni_new_attr_flags(struct ntfs_inode *ni, enum FILE_ATTRIBUTE new_fa);
5564534a70bSKonstantin Komarov enum REPARSE_SIGN ni_parse_reparse(struct ntfs_inode *ni, struct ATTRIB *attr,
557cd4c76ffSKonstantin Komarov 				   struct REPARSE_DATA_BUFFER *buffer);
5584534a70bSKonstantin Komarov int ni_write_inode(struct inode *inode, int sync, const char *hint);
5594534a70bSKonstantin Komarov #define _ni_write_inode(i, w) ni_write_inode(i, w, __func__)
5604534a70bSKonstantin Komarov int ni_fiemap(struct ntfs_inode *ni, struct fiemap_extent_info *fieinfo,
5614534a70bSKonstantin Komarov 	      __u64 vbo, __u64 len);
5624534a70bSKonstantin Komarov int ni_readpage_cmpr(struct ntfs_inode *ni, struct page *page);
5634534a70bSKonstantin Komarov int ni_decompress_file(struct ntfs_inode *ni);
5644534a70bSKonstantin Komarov int ni_read_frame(struct ntfs_inode *ni, u64 frame_vbo, struct page **pages,
5654534a70bSKonstantin Komarov 		  u32 pages_per_frame);
5664534a70bSKonstantin Komarov int ni_write_frame(struct ntfs_inode *ni, struct page **pages,
5674534a70bSKonstantin Komarov 		   u32 pages_per_frame);
56878ab59feSKonstantin Komarov int ni_remove_name(struct ntfs_inode *dir_ni, struct ntfs_inode *ni,
56978ab59feSKonstantin Komarov 		   struct NTFS_DE *de, struct NTFS_DE **de2, int *undo_step);
57078ab59feSKonstantin Komarov 
57178ab59feSKonstantin Komarov bool ni_remove_name_undo(struct ntfs_inode *dir_ni, struct ntfs_inode *ni,
57278ab59feSKonstantin Komarov 			 struct NTFS_DE *de, struct NTFS_DE *de2,
57378ab59feSKonstantin Komarov 			 int undo_step);
57478ab59feSKonstantin Komarov 
57578ab59feSKonstantin Komarov int ni_add_name(struct ntfs_inode *dir_ni, struct ntfs_inode *ni,
57678ab59feSKonstantin Komarov 		struct NTFS_DE *de);
57778ab59feSKonstantin Komarov 
57878ab59feSKonstantin Komarov int ni_rename(struct ntfs_inode *dir_ni, struct ntfs_inode *new_dir_ni,
57978ab59feSKonstantin Komarov 	      struct ntfs_inode *ni, struct NTFS_DE *de, struct NTFS_DE *new_de,
58078ab59feSKonstantin Komarov 	      bool *is_bad);
58178ab59feSKonstantin Komarov 
58278ab59feSKonstantin Komarov bool ni_is_dirty(struct inode *inode);
5834534a70bSKonstantin Komarov 
584e8b8e97fSKari Argillander /* Globals from fslog.c */
585ab84eee4SZeng Heng bool check_index_header(const struct INDEX_HDR *hdr, size_t bytes);
5864534a70bSKonstantin Komarov int log_replay(struct ntfs_inode *ni, bool *initialized);
5874534a70bSKonstantin Komarov 
588e8b8e97fSKari Argillander /* Globals from fsntfs.c */
589c55deec3SKonstantin Komarov struct buffer_head *ntfs_bread(struct super_block *sb, sector_t block);
5904534a70bSKonstantin Komarov bool ntfs_fix_pre_write(struct NTFS_RECORD_HEADER *rhdr, size_t bytes);
5914534a70bSKonstantin Komarov int ntfs_fix_post_read(struct NTFS_RECORD_HEADER *rhdr, size_t bytes,
5924534a70bSKonstantin Komarov 		       bool simple);
5934534a70bSKonstantin Komarov int ntfs_extend_init(struct ntfs_sb_info *sbi);
5944534a70bSKonstantin Komarov int ntfs_loadlog_and_replay(struct ntfs_inode *ni, struct ntfs_sb_info *sbi);
5954534a70bSKonstantin Komarov int ntfs_look_for_free_space(struct ntfs_sb_info *sbi, CLST lcn, CLST len,
5964534a70bSKonstantin Komarov 			     CLST *new_lcn, CLST *new_len,
5974534a70bSKonstantin Komarov 			     enum ALLOCATE_OPT opt);
598910013f7SKonstantin Komarov bool ntfs_check_for_free_space(struct ntfs_sb_info *sbi, CLST clen, CLST mlen);
5994534a70bSKonstantin Komarov int ntfs_look_free_mft(struct ntfs_sb_info *sbi, CLST *rno, bool mft,
6004534a70bSKonstantin Komarov 		       struct ntfs_inode *ni, struct mft_inode **mi);
601071100eaSKonstantin Komarov void ntfs_mark_rec_free(struct ntfs_sb_info *sbi, CLST rno, bool is_mft);
6024534a70bSKonstantin Komarov int ntfs_clear_mft_tail(struct ntfs_sb_info *sbi, size_t from, size_t to);
6034534a70bSKonstantin Komarov int ntfs_refresh_zone(struct ntfs_sb_info *sbi);
604e66af07cSPavel Skripkin void ntfs_update_mftmirr(struct ntfs_sb_info *sbi, int wait);
605c12df45eSKonstantin Komarov void ntfs_bad_inode(struct inode *inode, const char *hint);
606c12df45eSKonstantin Komarov #define _ntfs_bad_inode(i) ntfs_bad_inode(i, __func__)
6074534a70bSKonstantin Komarov enum NTFS_DIRTY_FLAGS {
6084534a70bSKonstantin Komarov 	NTFS_DIRTY_CLEAR = 0,
6094534a70bSKonstantin Komarov 	NTFS_DIRTY_DIRTY = 1,
6104534a70bSKonstantin Komarov 	NTFS_DIRTY_ERROR = 2,
6114534a70bSKonstantin Komarov };
6124534a70bSKonstantin Komarov int ntfs_set_state(struct ntfs_sb_info *sbi, enum NTFS_DIRTY_FLAGS dirty);
6134534a70bSKonstantin Komarov int ntfs_sb_read(struct super_block *sb, u64 lbo, size_t bytes, void *buffer);
6144534a70bSKonstantin Komarov int ntfs_sb_write(struct super_block *sb, u64 lbo, size_t bytes,
6154534a70bSKonstantin Komarov 		  const void *buffer, int wait);
6164534a70bSKonstantin Komarov int ntfs_sb_write_run(struct ntfs_sb_info *sbi, const struct runs_tree *run,
61763544672SKonstantin Komarov 		      u64 vbo, const void *buf, size_t bytes, int sync);
6184534a70bSKonstantin Komarov struct buffer_head *ntfs_bread_run(struct ntfs_sb_info *sbi,
6194534a70bSKonstantin Komarov 				   const struct runs_tree *run, u64 vbo);
6204534a70bSKonstantin Komarov int ntfs_read_run_nb(struct ntfs_sb_info *sbi, const struct runs_tree *run,
6214534a70bSKonstantin Komarov 		     u64 vbo, void *buf, u32 bytes, struct ntfs_buffers *nb);
6224534a70bSKonstantin Komarov int ntfs_read_bh(struct ntfs_sb_info *sbi, const struct runs_tree *run, u64 vbo,
6234534a70bSKonstantin Komarov 		 struct NTFS_RECORD_HEADER *rhdr, u32 bytes,
6244534a70bSKonstantin Komarov 		 struct ntfs_buffers *nb);
6254534a70bSKonstantin Komarov int ntfs_get_bh(struct ntfs_sb_info *sbi, const struct runs_tree *run, u64 vbo,
6264534a70bSKonstantin Komarov 		u32 bytes, struct ntfs_buffers *nb);
6274534a70bSKonstantin Komarov int ntfs_write_bh(struct ntfs_sb_info *sbi, struct NTFS_RECORD_HEADER *rhdr,
6284534a70bSKonstantin Komarov 		  struct ntfs_buffers *nb, int sync);
6294534a70bSKonstantin Komarov int ntfs_bio_pages(struct ntfs_sb_info *sbi, const struct runs_tree *run,
6304534a70bSKonstantin Komarov 		   struct page **pages, u32 nr_pages, u64 vbo, u32 bytes,
631ce6b5315SBart Van Assche 		   enum req_op op);
6324534a70bSKonstantin Komarov int ntfs_bio_fill_1(struct ntfs_sb_info *sbi, const struct runs_tree *run);
6334534a70bSKonstantin Komarov int ntfs_vbo_to_lbo(struct ntfs_sb_info *sbi, const struct runs_tree *run,
6344534a70bSKonstantin Komarov 		    u64 vbo, u64 *lbo, u64 *bytes);
6354534a70bSKonstantin Komarov struct ntfs_inode *ntfs_new_inode(struct ntfs_sb_info *sbi, CLST nRec,
636a81f47c4SKonstantin Komarov 				  enum RECORD_FLAG flag);
6374534a70bSKonstantin Komarov extern const u8 s_default_security[0x50];
6384534a70bSKonstantin Komarov bool is_sd_valid(const struct SECURITY_DESCRIPTOR_RELATIVE *sd, u32 len);
6394534a70bSKonstantin Komarov int ntfs_security_init(struct ntfs_sb_info *sbi);
6404534a70bSKonstantin Komarov int ntfs_get_security_by_id(struct ntfs_sb_info *sbi, __le32 security_id,
6414534a70bSKonstantin Komarov 			    struct SECURITY_DESCRIPTOR_RELATIVE **sd,
6424534a70bSKonstantin Komarov 			    size_t *size);
6434534a70bSKonstantin Komarov int ntfs_insert_security(struct ntfs_sb_info *sbi,
6444534a70bSKonstantin Komarov 			 const struct SECURITY_DESCRIPTOR_RELATIVE *sd,
6454534a70bSKonstantin Komarov 			 u32 size, __le32 *security_id, bool *inserted);
6464534a70bSKonstantin Komarov int ntfs_reparse_init(struct ntfs_sb_info *sbi);
6474534a70bSKonstantin Komarov int ntfs_objid_init(struct ntfs_sb_info *sbi);
6484534a70bSKonstantin Komarov int ntfs_objid_remove(struct ntfs_sb_info *sbi, struct GUID *guid);
6494534a70bSKonstantin Komarov int ntfs_insert_reparse(struct ntfs_sb_info *sbi, __le32 rtag,
6504534a70bSKonstantin Komarov 			const struct MFT_REF *ref);
6514534a70bSKonstantin Komarov int ntfs_remove_reparse(struct ntfs_sb_info *sbi, __le32 rtag,
6524534a70bSKonstantin Komarov 			const struct MFT_REF *ref);
6534534a70bSKonstantin Komarov void mark_as_free_ex(struct ntfs_sb_info *sbi, CLST lcn, CLST len, bool trim);
654a81f47c4SKonstantin Komarov int run_deallocate(struct ntfs_sb_info *sbi, const struct runs_tree *run,
655a81f47c4SKonstantin Komarov 		   bool trim);
6561d07a9dfSDaniel Pinto bool valid_windows_name(struct ntfs_sb_info *sbi, const struct le_str *name);
6577832e123SKonstantin Komarov int ntfs_set_label(struct ntfs_sb_info *sbi, u8 *label, int len);
6584534a70bSKonstantin Komarov 
659e8b8e97fSKari Argillander /* Globals from index.c */
6604534a70bSKonstantin Komarov int indx_used_bit(struct ntfs_index *indx, struct ntfs_inode *ni, size_t *bit);
6614534a70bSKonstantin Komarov void fnd_clear(struct ntfs_fnd *fnd);
fnd_get(void)6624534a70bSKonstantin Komarov static inline struct ntfs_fnd *fnd_get(void)
6634534a70bSKonstantin Komarov {
664195c52bdSKari Argillander 	return kzalloc(sizeof(struct ntfs_fnd), GFP_NOFS);
6654534a70bSKonstantin Komarov }
fnd_put(struct ntfs_fnd * fnd)6664534a70bSKonstantin Komarov static inline void fnd_put(struct ntfs_fnd *fnd)
6674534a70bSKonstantin Komarov {
6684534a70bSKonstantin Komarov 	if (fnd) {
6694534a70bSKonstantin Komarov 		fnd_clear(fnd);
670195c52bdSKari Argillander 		kfree(fnd);
6714534a70bSKonstantin Komarov 	}
6724534a70bSKonstantin Komarov }
6734534a70bSKonstantin Komarov void indx_clear(struct ntfs_index *idx);
6744534a70bSKonstantin Komarov int indx_init(struct ntfs_index *indx, struct ntfs_sb_info *sbi,
6754534a70bSKonstantin Komarov 	      const struct ATTRIB *attr, enum index_mutex_classed type);
6764534a70bSKonstantin Komarov struct INDEX_ROOT *indx_get_root(struct ntfs_index *indx, struct ntfs_inode *ni,
6774534a70bSKonstantin Komarov 				 struct ATTRIB **attr, struct mft_inode **mi);
6784534a70bSKonstantin Komarov int indx_read(struct ntfs_index *idx, struct ntfs_inode *ni, CLST vbn,
6794534a70bSKonstantin Komarov 	      struct indx_node **node);
6804534a70bSKonstantin Komarov int indx_find(struct ntfs_index *indx, struct ntfs_inode *dir,
6814534a70bSKonstantin Komarov 	      const struct INDEX_ROOT *root, const void *Key, size_t KeyLen,
6824534a70bSKonstantin Komarov 	      const void *param, int *diff, struct NTFS_DE **entry,
6834534a70bSKonstantin Komarov 	      struct ntfs_fnd *fnd);
6844534a70bSKonstantin Komarov int indx_find_sort(struct ntfs_index *indx, struct ntfs_inode *ni,
6854534a70bSKonstantin Komarov 		   const struct INDEX_ROOT *root, struct NTFS_DE **entry,
6864534a70bSKonstantin Komarov 		   struct ntfs_fnd *fnd);
6874534a70bSKonstantin Komarov int indx_find_raw(struct ntfs_index *indx, struct ntfs_inode *ni,
6884534a70bSKonstantin Komarov 		  const struct INDEX_ROOT *root, struct NTFS_DE **entry,
6894534a70bSKonstantin Komarov 		  size_t *off, struct ntfs_fnd *fnd);
6904534a70bSKonstantin Komarov int indx_insert_entry(struct ntfs_index *indx, struct ntfs_inode *ni,
6914534a70bSKonstantin Komarov 		      const struct NTFS_DE *new_de, const void *param,
69278ab59feSKonstantin Komarov 		      struct ntfs_fnd *fnd, bool undo);
6934534a70bSKonstantin Komarov int indx_delete_entry(struct ntfs_index *indx, struct ntfs_inode *ni,
6944534a70bSKonstantin Komarov 		      const void *key, u32 key_len, const void *param);
6954534a70bSKonstantin Komarov int indx_update_dup(struct ntfs_inode *ni, struct ntfs_sb_info *sbi,
6964534a70bSKonstantin Komarov 		    const struct ATTR_FILE_NAME *fname,
6974534a70bSKonstantin Komarov 		    const struct NTFS_DUP_INFO *dup, int sync);
6984534a70bSKonstantin Komarov 
699e8b8e97fSKari Argillander /* Globals from inode.c */
7004534a70bSKonstantin Komarov struct inode *ntfs_iget5(struct super_block *sb, const struct MFT_REF *ref,
7014534a70bSKonstantin Komarov 			 const struct cpu_str *name);
7024534a70bSKonstantin Komarov int ntfs_set_size(struct inode *inode, u64 new_size);
7034534a70bSKonstantin Komarov int reset_log_file(struct inode *inode);
7044534a70bSKonstantin Komarov int ntfs_get_block(struct inode *inode, sector_t vbn,
7054534a70bSKonstantin Komarov 		   struct buffer_head *bh_result, int create);
70644ab23b9SMatthew Wilcox (Oracle) int ntfs_write_begin(struct file *file, struct address_space *mapping,
70744ab23b9SMatthew Wilcox (Oracle) 		     loff_t pos, u32 len, struct page **pagep, void **fsdata);
70896de65a9SKonstantin Komarov int ntfs_write_end(struct file *file, struct address_space *mapping, loff_t pos,
70996de65a9SKonstantin Komarov 		   u32 len, u32 copied, struct page *page, void *fsdata);
7104534a70bSKonstantin Komarov int ntfs3_write_inode(struct inode *inode, struct writeback_control *wbc);
7114534a70bSKonstantin Komarov int ntfs_sync_inode(struct inode *inode);
7124534a70bSKonstantin Komarov int ntfs_flush_inodes(struct super_block *sb, struct inode *i1,
7134534a70bSKonstantin Komarov 		      struct inode *i2);
7144534a70bSKonstantin Komarov int inode_write_data(struct inode *inode, const void *data, size_t bytes);
715f0377761SKonstantin Komarov struct inode *ntfs_create_inode(struct mnt_idmap *idmap, struct inode *dir,
716f0377761SKonstantin Komarov 				struct dentry *dentry,
7174534a70bSKonstantin Komarov 				const struct cpu_str *uni, umode_t mode,
7184534a70bSKonstantin Komarov 				dev_t dev, const char *symname, u32 size,
7194534a70bSKonstantin Komarov 				struct ntfs_fnd *fnd);
7204534a70bSKonstantin Komarov int ntfs_link_inode(struct inode *inode, struct dentry *dentry);
7214534a70bSKonstantin Komarov int ntfs_unlink_inode(struct inode *dir, const struct dentry *dentry);
7224534a70bSKonstantin Komarov void ntfs_evict_inode(struct inode *inode);
7234534a70bSKonstantin Komarov extern const struct inode_operations ntfs_link_inode_operations;
7244534a70bSKonstantin Komarov extern const struct address_space_operations ntfs_aops;
7254534a70bSKonstantin Komarov extern const struct address_space_operations ntfs_aops_cmpr;
7264534a70bSKonstantin Komarov 
727e8b8e97fSKari Argillander /* Globals from name_i.c */
7284534a70bSKonstantin Komarov int fill_name_de(struct ntfs_sb_info *sbi, void *buf, const struct qstr *name,
7294534a70bSKonstantin Komarov 		 const struct cpu_str *uni);
7304534a70bSKonstantin Komarov struct dentry *ntfs3_get_parent(struct dentry *child);
7314534a70bSKonstantin Komarov 
7324534a70bSKonstantin Komarov extern const struct inode_operations ntfs_dir_inode_operations;
7334534a70bSKonstantin Komarov extern const struct inode_operations ntfs_special_inode_operations;
734a3a956c7SKonstantin Komarov extern const struct dentry_operations ntfs_dentry_ops;
7354534a70bSKonstantin Komarov 
736e8b8e97fSKari Argillander /* Globals from record.c */
7374534a70bSKonstantin Komarov int mi_get(struct ntfs_sb_info *sbi, CLST rno, struct mft_inode **mi);
7384534a70bSKonstantin Komarov void mi_put(struct mft_inode *mi);
7394534a70bSKonstantin Komarov int mi_init(struct mft_inode *mi, struct ntfs_sb_info *sbi, CLST rno);
7404534a70bSKonstantin Komarov int mi_read(struct mft_inode *mi, bool is_mft);
7414534a70bSKonstantin Komarov struct ATTRIB *mi_enum_attr(struct mft_inode *mi, struct ATTRIB *attr);
7424534a70bSKonstantin Komarov // TODO: id?
7434534a70bSKonstantin Komarov struct ATTRIB *mi_find_attr(struct mft_inode *mi, struct ATTRIB *attr,
7444534a70bSKonstantin Komarov 			    enum ATTR_TYPE type, const __le16 *name,
745a81f47c4SKonstantin Komarov 			    u8 name_len, const __le16 *id);
rec_find_attr_le(struct mft_inode * rec,struct ATTR_LIST_ENTRY * le)7464534a70bSKonstantin Komarov static inline struct ATTRIB *rec_find_attr_le(struct mft_inode *rec,
7474534a70bSKonstantin Komarov 					      struct ATTR_LIST_ENTRY *le)
7484534a70bSKonstantin Komarov {
7494534a70bSKonstantin Komarov 	return mi_find_attr(rec, NULL, le->type, le_name(le), le->name_len,
7504534a70bSKonstantin Komarov 			    &le->id);
7514534a70bSKonstantin Komarov }
7524534a70bSKonstantin Komarov int mi_write(struct mft_inode *mi, int wait);
7534534a70bSKonstantin Komarov int mi_format_new(struct mft_inode *mi, struct ntfs_sb_info *sbi, CLST rno,
7544534a70bSKonstantin Komarov 		  __le16 flags, bool is_mft);
7554534a70bSKonstantin Komarov struct ATTRIB *mi_insert_attr(struct mft_inode *mi, enum ATTR_TYPE type,
7564534a70bSKonstantin Komarov 			      const __le16 *name, u8 name_len, u32 asize,
7574534a70bSKonstantin Komarov 			      u16 name_off);
7584534a70bSKonstantin Komarov 
75978ab59feSKonstantin Komarov bool mi_remove_attr(struct ntfs_inode *ni, struct mft_inode *mi,
76078ab59feSKonstantin Komarov 		    struct ATTRIB *attr);
7614534a70bSKonstantin Komarov bool mi_resize_attr(struct mft_inode *mi, struct ATTRIB *attr, int bytes);
7624534a70bSKonstantin Komarov int mi_pack_runs(struct mft_inode *mi, struct ATTRIB *attr,
7634534a70bSKonstantin Komarov 		 struct runs_tree *run, CLST len);
mi_is_ref(const struct mft_inode * mi,const struct MFT_REF * ref)7644534a70bSKonstantin Komarov static inline bool mi_is_ref(const struct mft_inode *mi,
7654534a70bSKonstantin Komarov 			     const struct MFT_REF *ref)
7664534a70bSKonstantin Komarov {
7674534a70bSKonstantin Komarov 	if (le32_to_cpu(ref->low) != mi->rno)
7684534a70bSKonstantin Komarov 		return false;
7694534a70bSKonstantin Komarov 	if (ref->seq != mi->mrec->seq)
7704534a70bSKonstantin Komarov 		return false;
7714534a70bSKonstantin Komarov 
7724534a70bSKonstantin Komarov #ifdef CONFIG_NTFS3_64BIT_CLUSTER
7734534a70bSKonstantin Komarov 	return le16_to_cpu(ref->high) == (mi->rno >> 32);
7744534a70bSKonstantin Komarov #else
7754534a70bSKonstantin Komarov 	return !ref->high;
7764534a70bSKonstantin Komarov #endif
7774534a70bSKonstantin Komarov }
7784534a70bSKonstantin Komarov 
mi_get_ref(const struct mft_inode * mi,struct MFT_REF * ref)7794534a70bSKonstantin Komarov static inline void mi_get_ref(const struct mft_inode *mi, struct MFT_REF *ref)
7804534a70bSKonstantin Komarov {
7814534a70bSKonstantin Komarov 	ref->low = cpu_to_le32(mi->rno);
7824534a70bSKonstantin Komarov #ifdef CONFIG_NTFS3_64BIT_CLUSTER
7834534a70bSKonstantin Komarov 	ref->high = cpu_to_le16(mi->rno >> 32);
7844534a70bSKonstantin Komarov #else
7854534a70bSKonstantin Komarov 	ref->high = 0;
7864534a70bSKonstantin Komarov #endif
7874534a70bSKonstantin Komarov 	ref->seq = mi->mrec->seq;
7884534a70bSKonstantin Komarov }
7894534a70bSKonstantin Komarov 
790e8b8e97fSKari Argillander /* Globals from run.c */
7914534a70bSKonstantin Komarov bool run_lookup_entry(const struct runs_tree *run, CLST vcn, CLST *lcn,
7924534a70bSKonstantin Komarov 		      CLST *len, size_t *index);
7934534a70bSKonstantin Komarov void run_truncate(struct runs_tree *run, CLST vcn);
7944534a70bSKonstantin Komarov void run_truncate_head(struct runs_tree *run, CLST vcn);
7954534a70bSKonstantin Komarov void run_truncate_around(struct runs_tree *run, CLST vcn);
7964534a70bSKonstantin Komarov bool run_add_entry(struct runs_tree *run, CLST vcn, CLST lcn, CLST len,
7974534a70bSKonstantin Komarov 		   bool is_mft);
7984534a70bSKonstantin Komarov bool run_collapse_range(struct runs_tree *run, CLST vcn, CLST len);
799aa30eccbSKonstantin Komarov bool run_insert_range(struct runs_tree *run, CLST vcn, CLST len);
8004534a70bSKonstantin Komarov bool run_get_entry(const struct runs_tree *run, size_t index, CLST *vcn,
8014534a70bSKonstantin Komarov 		   CLST *lcn, CLST *len);
8024534a70bSKonstantin Komarov bool run_is_mapped_full(const struct runs_tree *run, CLST svcn, CLST evcn);
8034534a70bSKonstantin Komarov 
8044534a70bSKonstantin Komarov int run_pack(const struct runs_tree *run, CLST svcn, CLST len, u8 *run_buf,
8054534a70bSKonstantin Komarov 	     u32 run_buf_size, CLST *packed_vcns);
8064534a70bSKonstantin Komarov int run_unpack(struct runs_tree *run, struct ntfs_sb_info *sbi, CLST ino,
8074534a70bSKonstantin Komarov 	       CLST svcn, CLST evcn, CLST vcn, const u8 *run_buf,
8080e8235d2SKonstantin Komarov 	       int run_buf_size);
8094534a70bSKonstantin Komarov 
8104534a70bSKonstantin Komarov #ifdef NTFS3_CHECK_FREE_CLST
8114534a70bSKonstantin Komarov int run_unpack_ex(struct runs_tree *run, struct ntfs_sb_info *sbi, CLST ino,
8124534a70bSKonstantin Komarov 		  CLST svcn, CLST evcn, CLST vcn, const u8 *run_buf,
8130e8235d2SKonstantin Komarov 		  int run_buf_size);
8144534a70bSKonstantin Komarov #else
8154534a70bSKonstantin Komarov #define run_unpack_ex run_unpack
8164534a70bSKonstantin Komarov #endif
8174534a70bSKonstantin Komarov int run_get_highest_vcn(CLST vcn, const u8 *run_buf, u64 *highest_vcn);
81820abc64fSKonstantin Komarov int run_clone(const struct runs_tree *run, struct runs_tree *new_run);
8194534a70bSKonstantin Komarov 
820e8b8e97fSKari Argillander /* Globals from super.c */
8214534a70bSKonstantin Komarov void *ntfs_set_shared(void *ptr, u32 bytes);
8224534a70bSKonstantin Komarov void *ntfs_put_shared(void *ptr);
8234534a70bSKonstantin Komarov void ntfs_unmap_meta(struct super_block *sb, CLST lcn, CLST len);
8244534a70bSKonstantin Komarov int ntfs_discard(struct ntfs_sb_info *sbi, CLST Lcn, CLST Len);
8254534a70bSKonstantin Komarov 
826e8b8e97fSKari Argillander /* Globals from bitmap.c*/
8274534a70bSKonstantin Komarov int __init ntfs3_init_bitmap(void);
8284534a70bSKonstantin Komarov void ntfs3_exit_bitmap(void);
8294534a70bSKonstantin Komarov void wnd_close(struct wnd_bitmap *wnd);
wnd_zeroes(const struct wnd_bitmap * wnd)8304534a70bSKonstantin Komarov static inline size_t wnd_zeroes(const struct wnd_bitmap *wnd)
8314534a70bSKonstantin Komarov {
8324534a70bSKonstantin Komarov 	return wnd->total_zeroes;
8334534a70bSKonstantin Komarov }
8344534a70bSKonstantin Komarov int wnd_init(struct wnd_bitmap *wnd, struct super_block *sb, size_t nbits);
8354534a70bSKonstantin Komarov int wnd_set_free(struct wnd_bitmap *wnd, size_t bit, size_t bits);
8364534a70bSKonstantin Komarov int wnd_set_used(struct wnd_bitmap *wnd, size_t bit, size_t bits);
837ec5fc720SKonstantin Komarov int wnd_set_used_safe(struct wnd_bitmap *wnd, size_t bit, size_t bits,
838ec5fc720SKonstantin Komarov 		      size_t *done);
8394534a70bSKonstantin Komarov bool wnd_is_free(struct wnd_bitmap *wnd, size_t bit, size_t bits);
8404534a70bSKonstantin Komarov bool wnd_is_used(struct wnd_bitmap *wnd, size_t bit, size_t bits);
8414534a70bSKonstantin Komarov 
842e8b8e97fSKari Argillander /* Possible values for 'flags' 'wnd_find'. */
8434534a70bSKonstantin Komarov #define BITMAP_FIND_MARK_AS_USED 0x01
8444534a70bSKonstantin Komarov #define BITMAP_FIND_FULL 0x02
8454534a70bSKonstantin Komarov size_t wnd_find(struct wnd_bitmap *wnd, size_t to_alloc, size_t hint,
8464534a70bSKonstantin Komarov 		size_t flags, size_t *allocated);
8474534a70bSKonstantin Komarov int wnd_extend(struct wnd_bitmap *wnd, size_t new_bits);
8484534a70bSKonstantin Komarov void wnd_zone_set(struct wnd_bitmap *wnd, size_t Lcn, size_t Len);
8494534a70bSKonstantin Komarov int ntfs_trim_fs(struct ntfs_sb_info *sbi, struct fstrim_range *range);
8504534a70bSKonstantin Komarov 
85108811ba5SKonstantin Komarov void ntfs_bitmap_set_le(void *map, unsigned int start, int len);
85208811ba5SKonstantin Komarov void ntfs_bitmap_clear_le(void *map, unsigned int start, int len);
85308811ba5SKonstantin Komarov unsigned int ntfs_bitmap_weight_le(const void *bitmap, int bits);
85488a8d0d2SThomas Kühnel 
855e8b8e97fSKari Argillander /* Globals from upcase.c */
8564534a70bSKonstantin Komarov int ntfs_cmp_names(const __le16 *s1, size_t l1, const __le16 *s2, size_t l2,
8574534a70bSKonstantin Komarov 		   const u16 *upcase, bool bothcase);
8584534a70bSKonstantin Komarov int ntfs_cmp_names_cpu(const struct cpu_str *uni1, const struct le_str *uni2,
8594534a70bSKonstantin Komarov 		       const u16 *upcase, bool bothcase);
860a3a956c7SKonstantin Komarov unsigned long ntfs_names_hash(const u16 *name, size_t len, const u16 *upcase,
861a3a956c7SKonstantin Komarov 			      unsigned long hash);
8624534a70bSKonstantin Komarov 
8634534a70bSKonstantin Komarov /* globals from xattr.c */
8644534a70bSKonstantin Komarov #ifdef CONFIG_NTFS3_FS_POSIX_ACL
865f0377761SKonstantin Komarov struct posix_acl *ntfs_get_acl(struct mnt_idmap *idmap, struct dentry *dentry,
866f0377761SKonstantin Komarov 			       int type);
86713e83a49SChristian Brauner int ntfs_set_acl(struct mnt_idmap *idmap, struct dentry *dentry,
8684534a70bSKonstantin Komarov 		 struct posix_acl *acl, int type);
869700b7940SChristian Brauner int ntfs_init_acl(struct mnt_idmap *idmap, struct inode *inode,
8704534a70bSKonstantin Komarov 		  struct inode *dir);
8714534a70bSKonstantin Komarov #else
8724534a70bSKonstantin Komarov #define ntfs_get_acl NULL
8734534a70bSKonstantin Komarov #define ntfs_set_acl NULL
8744534a70bSKonstantin Komarov #endif
8754534a70bSKonstantin Komarov 
87613e83a49SChristian Brauner int ntfs_acl_chmod(struct mnt_idmap *idmap, struct dentry *dentry);
8774534a70bSKonstantin Komarov ssize_t ntfs_listxattr(struct dentry *dentry, char *buffer, size_t size);
8784534a70bSKonstantin Komarov extern const struct xattr_handler *ntfs_xattr_handlers[];
8794534a70bSKonstantin Komarov 
8801842fbc8SKonstantin Komarov int ntfs_save_wsl_perm(struct inode *inode, __le16 *ea_size);
8814534a70bSKonstantin Komarov void ntfs_get_wsl_perm(struct inode *inode);
8824534a70bSKonstantin Komarov 
8834534a70bSKonstantin Komarov /* globals from lznt.c */
8844534a70bSKonstantin Komarov struct lznt *get_lznt_ctx(int level);
8854534a70bSKonstantin Komarov size_t compress_lznt(const void *uncompressed, size_t uncompressed_size,
8864534a70bSKonstantin Komarov 		     void *compressed, size_t compressed_size,
8874534a70bSKonstantin Komarov 		     struct lznt *ctx);
8884534a70bSKonstantin Komarov ssize_t decompress_lznt(const void *compressed, size_t compressed_size,
8894534a70bSKonstantin Komarov 			void *uncompressed, size_t uncompressed_size);
8904534a70bSKonstantin Komarov 
is_ntfs3(struct ntfs_sb_info * sbi)8914534a70bSKonstantin Komarov static inline bool is_ntfs3(struct ntfs_sb_info *sbi)
8924534a70bSKonstantin Komarov {
8934534a70bSKonstantin Komarov 	return sbi->volume.major_ver >= 3;
8944534a70bSKonstantin Komarov }
8954534a70bSKonstantin Komarov 
8964534a70bSKonstantin Komarov /* (sb->s_flags & SB_ACTIVE) */
is_mounted(struct ntfs_sb_info * sbi)8974534a70bSKonstantin Komarov static inline bool is_mounted(struct ntfs_sb_info *sbi)
8984534a70bSKonstantin Komarov {
8994534a70bSKonstantin Komarov 	return !!sbi->sb->s_root;
9004534a70bSKonstantin Komarov }
9014534a70bSKonstantin Komarov 
ntfs_is_meta_file(struct ntfs_sb_info * sbi,CLST rno)9024534a70bSKonstantin Komarov static inline bool ntfs_is_meta_file(struct ntfs_sb_info *sbi, CLST rno)
9034534a70bSKonstantin Komarov {
9044534a70bSKonstantin Komarov 	return rno < MFT_REC_FREE || rno == sbi->objid_no ||
9054534a70bSKonstantin Komarov 	       rno == sbi->quota_no || rno == sbi->reparse_no ||
9064534a70bSKonstantin Komarov 	       rno == sbi->usn_jrnl_no;
9074534a70bSKonstantin Komarov }
9084534a70bSKonstantin Komarov 
ntfs_unmap_page(struct page * page)9094534a70bSKonstantin Komarov static inline void ntfs_unmap_page(struct page *page)
9104534a70bSKonstantin Komarov {
9114534a70bSKonstantin Komarov 	kunmap(page);
9124534a70bSKonstantin Komarov 	put_page(page);
9134534a70bSKonstantin Komarov }
9144534a70bSKonstantin Komarov 
ntfs_map_page(struct address_space * mapping,unsigned long index)9154534a70bSKonstantin Komarov static inline struct page *ntfs_map_page(struct address_space *mapping,
9164534a70bSKonstantin Komarov 					 unsigned long index)
9174534a70bSKonstantin Komarov {
9184534a70bSKonstantin Komarov 	struct page *page = read_mapping_page(mapping, index, NULL);
9194534a70bSKonstantin Komarov 
92019cb4273SMatthew Wilcox (Oracle) 	if (!IS_ERR(page))
9214534a70bSKonstantin Komarov 		kmap(page);
9224534a70bSKonstantin Komarov 	return page;
9234534a70bSKonstantin Komarov }
9244534a70bSKonstantin Komarov 
wnd_zone_bit(const struct wnd_bitmap * wnd)9254534a70bSKonstantin Komarov static inline size_t wnd_zone_bit(const struct wnd_bitmap *wnd)
9264534a70bSKonstantin Komarov {
9274534a70bSKonstantin Komarov 	return wnd->zone_bit;
9284534a70bSKonstantin Komarov }
9294534a70bSKonstantin Komarov 
wnd_zone_len(const struct wnd_bitmap * wnd)9304534a70bSKonstantin Komarov static inline size_t wnd_zone_len(const struct wnd_bitmap *wnd)
9314534a70bSKonstantin Komarov {
9324534a70bSKonstantin Komarov 	return wnd->zone_end - wnd->zone_bit;
9334534a70bSKonstantin Komarov }
9344534a70bSKonstantin Komarov 
run_init(struct runs_tree * run)9354534a70bSKonstantin Komarov static inline void run_init(struct runs_tree *run)
9364534a70bSKonstantin Komarov {
9374534a70bSKonstantin Komarov 	run->runs = NULL;
9384534a70bSKonstantin Komarov 	run->count = 0;
9394534a70bSKonstantin Komarov 	run->allocated = 0;
9404534a70bSKonstantin Komarov }
9414534a70bSKonstantin Komarov 
run_alloc(void)9424534a70bSKonstantin Komarov static inline struct runs_tree *run_alloc(void)
9434534a70bSKonstantin Komarov {
944195c52bdSKari Argillander 	return kzalloc(sizeof(struct runs_tree), GFP_NOFS);
9454534a70bSKonstantin Komarov }
9464534a70bSKonstantin Komarov 
run_close(struct runs_tree * run)9474534a70bSKonstantin Komarov static inline void run_close(struct runs_tree *run)
9484534a70bSKonstantin Komarov {
949195c52bdSKari Argillander 	kvfree(run->runs);
9504534a70bSKonstantin Komarov 	memset(run, 0, sizeof(*run));
9514534a70bSKonstantin Komarov }
9524534a70bSKonstantin Komarov 
run_free(struct runs_tree * run)9534534a70bSKonstantin Komarov static inline void run_free(struct runs_tree *run)
9544534a70bSKonstantin Komarov {
9554534a70bSKonstantin Komarov 	if (run) {
956195c52bdSKari Argillander 		kvfree(run->runs);
957195c52bdSKari Argillander 		kfree(run);
9584534a70bSKonstantin Komarov 	}
9594534a70bSKonstantin Komarov }
9604534a70bSKonstantin Komarov 
run_is_empty(struct runs_tree * run)9614534a70bSKonstantin Komarov static inline bool run_is_empty(struct runs_tree *run)
9624534a70bSKonstantin Komarov {
9634534a70bSKonstantin Komarov 	return !run->count;
9644534a70bSKonstantin Komarov }
9654534a70bSKonstantin Komarov 
966e8b8e97fSKari Argillander /* NTFS uses quad aligned bitmaps. */
ntfs3_bitmap_size(size_t bits)967*706cc802SAlexander Lobakin static inline size_t ntfs3_bitmap_size(size_t bits)
9684534a70bSKonstantin Komarov {
969*706cc802SAlexander Lobakin 	return BITS_TO_U64(bits) * sizeof(u64);
9704534a70bSKonstantin Komarov }
9714534a70bSKonstantin Komarov 
9724534a70bSKonstantin Komarov #define _100ns2seconds 10000000
9734534a70bSKonstantin Komarov #define SecondsToStartOf1970 0x00000002B6109100
9744534a70bSKonstantin Komarov 
9754534a70bSKonstantin Komarov #define NTFS_TIME_GRAN 100
9764534a70bSKonstantin Komarov 
9774534a70bSKonstantin Komarov /*
978e8b8e97fSKari Argillander  * kernel2nt - Converts in-memory kernel timestamp into nt time.
9794534a70bSKonstantin Komarov  */
kernel2nt(const struct timespec64 * ts)9804534a70bSKonstantin Komarov static inline __le64 kernel2nt(const struct timespec64 *ts)
9814534a70bSKonstantin Komarov {
9824534a70bSKonstantin Komarov 	// 10^7 units of 100 nanoseconds one second
9834534a70bSKonstantin Komarov 	return cpu_to_le64(_100ns2seconds *
9844534a70bSKonstantin Komarov 				   (ts->tv_sec + SecondsToStartOf1970) +
9854534a70bSKonstantin Komarov 			   ts->tv_nsec / NTFS_TIME_GRAN);
9864534a70bSKonstantin Komarov }
9874534a70bSKonstantin Komarov 
9884534a70bSKonstantin Komarov /*
989e8b8e97fSKari Argillander  * nt2kernel - Converts on-disk nt time into kernel timestamp.
9904534a70bSKonstantin Komarov  */
nt2kernel(const __le64 tm,struct timespec64 * ts)9914534a70bSKonstantin Komarov static inline void nt2kernel(const __le64 tm, struct timespec64 *ts)
9924534a70bSKonstantin Komarov {
9934534a70bSKonstantin Komarov 	u64 t = le64_to_cpu(tm) - _100ns2seconds * SecondsToStartOf1970;
9944534a70bSKonstantin Komarov 
9954534a70bSKonstantin Komarov 	// WARNING: do_div changes its first argument(!)
9964534a70bSKonstantin Komarov 	ts->tv_nsec = do_div(t, _100ns2seconds) * 100;
9974534a70bSKonstantin Komarov 	ts->tv_sec = t;
9984534a70bSKonstantin Komarov }
9994534a70bSKonstantin Komarov 
ntfs_sb(struct super_block * sb)10004534a70bSKonstantin Komarov static inline struct ntfs_sb_info *ntfs_sb(struct super_block *sb)
10014534a70bSKonstantin Komarov {
10024534a70bSKonstantin Komarov 	return sb->s_fs_info;
10034534a70bSKonstantin Komarov }
10044534a70bSKonstantin Komarov 
ntfs3_forced_shutdown(struct super_block * sb)1005323b0ab3SKonstantin Komarov static inline int ntfs3_forced_shutdown(struct super_block *sb)
1006f73f9397SKonstantin Komarov {
1007323b0ab3SKonstantin Komarov 	return test_bit(NTFS_FLAGS_SHUTDOWN_BIT, &ntfs_sb(sb)->flags);
1008f73f9397SKonstantin Komarov }
1009f73f9397SKonstantin Komarov 
1010e8b8e97fSKari Argillander /*
1011e8b8e97fSKari Argillander  * ntfs_up_cluster - Align up on cluster boundary.
1012e8b8e97fSKari Argillander  */
ntfs_up_cluster(const struct ntfs_sb_info * sbi,u64 size)10134534a70bSKonstantin Komarov static inline u64 ntfs_up_cluster(const struct ntfs_sb_info *sbi, u64 size)
10144534a70bSKonstantin Komarov {
10154534a70bSKonstantin Komarov 	return (size + sbi->cluster_mask) & sbi->cluster_mask_inv;
10164534a70bSKonstantin Komarov }
10174534a70bSKonstantin Komarov 
1018e8b8e97fSKari Argillander /*
1019e8b8e97fSKari Argillander  * ntfs_up_block - Align up on cluster boundary.
1020e8b8e97fSKari Argillander  */
ntfs_up_block(const struct super_block * sb,u64 size)10214534a70bSKonstantin Komarov static inline u64 ntfs_up_block(const struct super_block *sb, u64 size)
10224534a70bSKonstantin Komarov {
10234534a70bSKonstantin Komarov 	return (size + sb->s_blocksize - 1) & ~(u64)(sb->s_blocksize - 1);
10244534a70bSKonstantin Komarov }
10254534a70bSKonstantin Komarov 
bytes_to_cluster(const struct ntfs_sb_info * sbi,u64 size)10264534a70bSKonstantin Komarov static inline CLST bytes_to_cluster(const struct ntfs_sb_info *sbi, u64 size)
10274534a70bSKonstantin Komarov {
10284534a70bSKonstantin Komarov 	return (size + sbi->cluster_mask) >> sbi->cluster_bits;
10294534a70bSKonstantin Komarov }
10304534a70bSKonstantin Komarov 
bytes_to_block(const struct super_block * sb,u64 size)10314534a70bSKonstantin Komarov static inline u64 bytes_to_block(const struct super_block *sb, u64 size)
10324534a70bSKonstantin Komarov {
10334534a70bSKonstantin Komarov 	return (size + sb->s_blocksize - 1) >> sb->s_blocksize_bits;
10344534a70bSKonstantin Komarov }
10354534a70bSKonstantin Komarov 
ntfs_i(struct inode * inode)10364534a70bSKonstantin Komarov static inline struct ntfs_inode *ntfs_i(struct inode *inode)
10374534a70bSKonstantin Komarov {
10384534a70bSKonstantin Komarov 	return container_of(inode, struct ntfs_inode, vfs_inode);
10394534a70bSKonstantin Komarov }
10404534a70bSKonstantin Komarov 
is_compressed(const struct ntfs_inode * ni)10414534a70bSKonstantin Komarov static inline bool is_compressed(const struct ntfs_inode *ni)
10424534a70bSKonstantin Komarov {
10434534a70bSKonstantin Komarov 	return (ni->std_fa & FILE_ATTRIBUTE_COMPRESSED) ||
10444534a70bSKonstantin Komarov 	       (ni->ni_flags & NI_FLAG_COMPRESSED_MASK);
10454534a70bSKonstantin Komarov }
10464534a70bSKonstantin Komarov 
ni_ext_compress_bits(const struct ntfs_inode * ni)10474534a70bSKonstantin Komarov static inline int ni_ext_compress_bits(const struct ntfs_inode *ni)
10484534a70bSKonstantin Komarov {
10494534a70bSKonstantin Komarov 	return 0xb + (ni->ni_flags & NI_FLAG_COMPRESSED_MASK);
10504534a70bSKonstantin Komarov }
10514534a70bSKonstantin Komarov 
1052e8b8e97fSKari Argillander /* Bits - 0xc, 0xd, 0xe, 0xf, 0x10 */
ni_set_ext_compress_bits(struct ntfs_inode * ni,u8 bits)10534534a70bSKonstantin Komarov static inline void ni_set_ext_compress_bits(struct ntfs_inode *ni, u8 bits)
10544534a70bSKonstantin Komarov {
10554534a70bSKonstantin Komarov 	ni->ni_flags |= (bits - 0xb) & NI_FLAG_COMPRESSED_MASK;
10564534a70bSKonstantin Komarov }
10574534a70bSKonstantin Komarov 
is_dedup(const struct ntfs_inode * ni)10584534a70bSKonstantin Komarov static inline bool is_dedup(const struct ntfs_inode *ni)
10594534a70bSKonstantin Komarov {
10604534a70bSKonstantin Komarov 	return ni->ni_flags & NI_FLAG_DEDUPLICATED;
10614534a70bSKonstantin Komarov }
10624534a70bSKonstantin Komarov 
is_encrypted(const struct ntfs_inode * ni)10634534a70bSKonstantin Komarov static inline bool is_encrypted(const struct ntfs_inode *ni)
10644534a70bSKonstantin Komarov {
10654534a70bSKonstantin Komarov 	return ni->std_fa & FILE_ATTRIBUTE_ENCRYPTED;
10664534a70bSKonstantin Komarov }
10674534a70bSKonstantin Komarov 
is_sparsed(const struct ntfs_inode * ni)10684534a70bSKonstantin Komarov static inline bool is_sparsed(const struct ntfs_inode *ni)
10694534a70bSKonstantin Komarov {
10704534a70bSKonstantin Komarov 	return ni->std_fa & FILE_ATTRIBUTE_SPARSE_FILE;
10714534a70bSKonstantin Komarov }
10724534a70bSKonstantin Komarov 
is_resident(struct ntfs_inode * ni)10734534a70bSKonstantin Komarov static inline int is_resident(struct ntfs_inode *ni)
10744534a70bSKonstantin Komarov {
10754534a70bSKonstantin Komarov 	return ni->ni_flags & NI_FLAG_RESIDENT;
10764534a70bSKonstantin Komarov }
10774534a70bSKonstantin Komarov 
le16_sub_cpu(__le16 * var,u16 val)10784534a70bSKonstantin Komarov static inline void le16_sub_cpu(__le16 *var, u16 val)
10794534a70bSKonstantin Komarov {
10804534a70bSKonstantin Komarov 	*var = cpu_to_le16(le16_to_cpu(*var) - val);
10814534a70bSKonstantin Komarov }
10824534a70bSKonstantin Komarov 
le32_sub_cpu(__le32 * var,u32 val)10834534a70bSKonstantin Komarov static inline void le32_sub_cpu(__le32 *var, u32 val)
10844534a70bSKonstantin Komarov {
10854534a70bSKonstantin Komarov 	*var = cpu_to_le32(le32_to_cpu(*var) - val);
10864534a70bSKonstantin Komarov }
10874534a70bSKonstantin Komarov 
nb_put(struct ntfs_buffers * nb)10884534a70bSKonstantin Komarov static inline void nb_put(struct ntfs_buffers *nb)
10894534a70bSKonstantin Komarov {
10904534a70bSKonstantin Komarov 	u32 i, nbufs = nb->nbufs;
10914534a70bSKonstantin Komarov 
10924534a70bSKonstantin Komarov 	if (!nbufs)
10934534a70bSKonstantin Komarov 		return;
10944534a70bSKonstantin Komarov 
10954534a70bSKonstantin Komarov 	for (i = 0; i < nbufs; i++)
10964534a70bSKonstantin Komarov 		put_bh(nb->bh[i]);
10974534a70bSKonstantin Komarov 	nb->nbufs = 0;
10984534a70bSKonstantin Komarov }
10994534a70bSKonstantin Komarov 
put_indx_node(struct indx_node * in)11004534a70bSKonstantin Komarov static inline void put_indx_node(struct indx_node *in)
11014534a70bSKonstantin Komarov {
11024534a70bSKonstantin Komarov 	if (!in)
11034534a70bSKonstantin Komarov 		return;
11044534a70bSKonstantin Komarov 
1105195c52bdSKari Argillander 	kfree(in->index);
11064534a70bSKonstantin Komarov 	nb_put(&in->nb);
1107195c52bdSKari Argillander 	kfree(in);
11084534a70bSKonstantin Komarov }
11094534a70bSKonstantin Komarov 
mi_clear(struct mft_inode * mi)11104534a70bSKonstantin Komarov static inline void mi_clear(struct mft_inode *mi)
11114534a70bSKonstantin Komarov {
11124534a70bSKonstantin Komarov 	nb_put(&mi->nb);
1113195c52bdSKari Argillander 	kfree(mi->mrec);
11144534a70bSKonstantin Komarov 	mi->mrec = NULL;
11154534a70bSKonstantin Komarov }
11164534a70bSKonstantin Komarov 
ni_lock(struct ntfs_inode * ni)11174534a70bSKonstantin Komarov static inline void ni_lock(struct ntfs_inode *ni)
11184534a70bSKonstantin Komarov {
11194534a70bSKonstantin Komarov 	mutex_lock_nested(&ni->ni_lock, NTFS_INODE_MUTEX_NORMAL);
11204534a70bSKonstantin Komarov }
11214534a70bSKonstantin Komarov 
ni_lock_dir(struct ntfs_inode * ni)11224534a70bSKonstantin Komarov static inline void ni_lock_dir(struct ntfs_inode *ni)
11234534a70bSKonstantin Komarov {
11244534a70bSKonstantin Komarov 	mutex_lock_nested(&ni->ni_lock, NTFS_INODE_MUTEX_PARENT);
11254534a70bSKonstantin Komarov }
11264534a70bSKonstantin Komarov 
ni_lock_dir2(struct ntfs_inode * ni)11270ad9dfcbSKonstantin Komarov static inline void ni_lock_dir2(struct ntfs_inode *ni)
11280ad9dfcbSKonstantin Komarov {
11290ad9dfcbSKonstantin Komarov 	mutex_lock_nested(&ni->ni_lock, NTFS_INODE_MUTEX_PARENT2);
11300ad9dfcbSKonstantin Komarov }
11310ad9dfcbSKonstantin Komarov 
ni_unlock(struct ntfs_inode * ni)11324534a70bSKonstantin Komarov static inline void ni_unlock(struct ntfs_inode *ni)
11334534a70bSKonstantin Komarov {
11344534a70bSKonstantin Komarov 	mutex_unlock(&ni->ni_lock);
11354534a70bSKonstantin Komarov }
11364534a70bSKonstantin Komarov 
ni_trylock(struct ntfs_inode * ni)11374534a70bSKonstantin Komarov static inline int ni_trylock(struct ntfs_inode *ni)
11384534a70bSKonstantin Komarov {
11394534a70bSKonstantin Komarov 	return mutex_trylock(&ni->ni_lock);
11404534a70bSKonstantin Komarov }
11414534a70bSKonstantin Komarov 
attr_load_runs_attr(struct ntfs_inode * ni,struct ATTRIB * attr,struct runs_tree * run,CLST vcn)11424534a70bSKonstantin Komarov static inline int attr_load_runs_attr(struct ntfs_inode *ni,
11434534a70bSKonstantin Komarov 				      struct ATTRIB *attr,
11444534a70bSKonstantin Komarov 				      struct runs_tree *run, CLST vcn)
11454534a70bSKonstantin Komarov {
11464534a70bSKonstantin Komarov 	return attr_load_runs_vcn(ni, attr->type, attr_name(attr),
11474534a70bSKonstantin Komarov 				  attr->name_len, run, vcn);
11484534a70bSKonstantin Komarov }
11494534a70bSKonstantin Komarov 
le64_sub_cpu(__le64 * var,u64 val)11504534a70bSKonstantin Komarov static inline void le64_sub_cpu(__le64 *var, u64 val)
11514534a70bSKonstantin Komarov {
11524534a70bSKonstantin Komarov 	*var = cpu_to_le64(le64_to_cpu(*var) - val);
11534534a70bSKonstantin Komarov }
115487790b65SKari Argillander 
115587790b65SKari Argillander #endif /* _LINUX_NTFS3_NTFS_FS_H */
1156