162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci *
462306a36Sopenharmony_ci * Copyright (C) 2019-2021 Paragon Software GmbH, All rights reserved.
562306a36Sopenharmony_ci *
662306a36Sopenharmony_ci */
762306a36Sopenharmony_ci
862306a36Sopenharmony_ci// clang-format off
962306a36Sopenharmony_ci#ifndef _LINUX_NTFS3_NTFS_FS_H
1062306a36Sopenharmony_ci#define _LINUX_NTFS3_NTFS_FS_H
1162306a36Sopenharmony_ci
1262306a36Sopenharmony_ci#include <linux/blkdev.h>
1362306a36Sopenharmony_ci#include <linux/buffer_head.h>
1462306a36Sopenharmony_ci#include <linux/fs.h>
1562306a36Sopenharmony_ci#include <linux/highmem.h>
1662306a36Sopenharmony_ci#include <linux/kernel.h>
1762306a36Sopenharmony_ci#include <linux/mm.h>
1862306a36Sopenharmony_ci#include <linux/mutex.h>
1962306a36Sopenharmony_ci#include <linux/page-flags.h>
2062306a36Sopenharmony_ci#include <linux/pagemap.h>
2162306a36Sopenharmony_ci#include <linux/rbtree.h>
2262306a36Sopenharmony_ci#include <linux/rwsem.h>
2362306a36Sopenharmony_ci#include <linux/slab.h>
2462306a36Sopenharmony_ci#include <linux/string.h>
2562306a36Sopenharmony_ci#include <linux/time64.h>
2662306a36Sopenharmony_ci#include <linux/types.h>
2762306a36Sopenharmony_ci#include <linux/uidgid.h>
2862306a36Sopenharmony_ci#include <asm/div64.h>
2962306a36Sopenharmony_ci#include <asm/page.h>
3062306a36Sopenharmony_ci
3162306a36Sopenharmony_ci#include "debug.h"
3262306a36Sopenharmony_ci#include "ntfs.h"
3362306a36Sopenharmony_ci
3462306a36Sopenharmony_cistruct dentry;
3562306a36Sopenharmony_cistruct fiemap_extent_info;
3662306a36Sopenharmony_cistruct user_namespace;
3762306a36Sopenharmony_cistruct page;
3862306a36Sopenharmony_cistruct writeback_control;
3962306a36Sopenharmony_cienum utf16_endian;
4062306a36Sopenharmony_ci
4162306a36Sopenharmony_ci
4262306a36Sopenharmony_ci#define MINUS_ONE_T			((size_t)(-1))
4362306a36Sopenharmony_ci/* Biggest MFT / smallest cluster */
4462306a36Sopenharmony_ci#define MAXIMUM_BYTES_PER_MFT		4096
4562306a36Sopenharmony_ci#define MAXIMUM_SHIFT_BYTES_PER_MFT	12
4662306a36Sopenharmony_ci#define NTFS_BLOCKS_PER_MFT_RECORD	(MAXIMUM_BYTES_PER_MFT / 512)
4762306a36Sopenharmony_ci
4862306a36Sopenharmony_ci#define MAXIMUM_BYTES_PER_INDEX		4096
4962306a36Sopenharmony_ci#define MAXIMUM_SHIFT_BYTES_PER_INDEX	12
5062306a36Sopenharmony_ci#define NTFS_BLOCKS_PER_INODE		(MAXIMUM_BYTES_PER_INDEX / 512)
5162306a36Sopenharmony_ci
5262306a36Sopenharmony_ci/* NTFS specific error code when fixup failed. */
5362306a36Sopenharmony_ci#define E_NTFS_FIXUP			555
5462306a36Sopenharmony_ci/* NTFS specific error code about resident->nonresident. */
5562306a36Sopenharmony_ci#define E_NTFS_NONRESIDENT		556
5662306a36Sopenharmony_ci/* NTFS specific error code about punch hole. */
5762306a36Sopenharmony_ci#define E_NTFS_NOTALIGNED		557
5862306a36Sopenharmony_ci/* NTFS specific error code when on-disk struct is corrupted. */
5962306a36Sopenharmony_ci#define E_NTFS_CORRUPT			558
6062306a36Sopenharmony_ci
6162306a36Sopenharmony_ci
6262306a36Sopenharmony_ci/* sbi->flags */
6362306a36Sopenharmony_ci#define NTFS_FLAGS_NODISCARD		0x00000001
6462306a36Sopenharmony_ci/* ntfs in shutdown state. */
6562306a36Sopenharmony_ci#define NTFS_FLAGS_SHUTDOWN_BIT		0x00000002  /* == 4*/
6662306a36Sopenharmony_ci/* Set when LogFile is replaying. */
6762306a36Sopenharmony_ci#define NTFS_FLAGS_LOG_REPLAYING	0x00000008
6862306a36Sopenharmony_ci/* Set when we changed first MFT's which copy must be updated in $MftMirr. */
6962306a36Sopenharmony_ci#define NTFS_FLAGS_MFTMIRR		0x00001000
7062306a36Sopenharmony_ci#define NTFS_FLAGS_NEED_REPLAY		0x04000000
7162306a36Sopenharmony_ci
7262306a36Sopenharmony_ci
7362306a36Sopenharmony_ci/* ni->ni_flags */
7462306a36Sopenharmony_ci/*
7562306a36Sopenharmony_ci * Data attribute is external compressed (LZX/Xpress)
7662306a36Sopenharmony_ci * 1 - WOF_COMPRESSION_XPRESS4K
7762306a36Sopenharmony_ci * 2 - WOF_COMPRESSION_XPRESS8K
7862306a36Sopenharmony_ci * 3 - WOF_COMPRESSION_XPRESS16K
7962306a36Sopenharmony_ci * 4 - WOF_COMPRESSION_LZX32K
8062306a36Sopenharmony_ci */
8162306a36Sopenharmony_ci#define NI_FLAG_COMPRESSED_MASK		0x0000000f
8262306a36Sopenharmony_ci/* Data attribute is deduplicated. */
8362306a36Sopenharmony_ci#define NI_FLAG_DEDUPLICATED		0x00000010
8462306a36Sopenharmony_ci#define NI_FLAG_EA			0x00000020
8562306a36Sopenharmony_ci#define NI_FLAG_DIR			0x00000040
8662306a36Sopenharmony_ci#define NI_FLAG_RESIDENT		0x00000080
8762306a36Sopenharmony_ci#define NI_FLAG_UPDATE_PARENT		0x00000100
8862306a36Sopenharmony_ci// clang-format on
8962306a36Sopenharmony_ci
9062306a36Sopenharmony_cistruct ntfs_mount_options {
9162306a36Sopenharmony_ci	char *nls_name;
9262306a36Sopenharmony_ci	struct nls_table *nls;
9362306a36Sopenharmony_ci
9462306a36Sopenharmony_ci	kuid_t fs_uid;
9562306a36Sopenharmony_ci	kgid_t fs_gid;
9662306a36Sopenharmony_ci	u16 fs_fmask_inv;
9762306a36Sopenharmony_ci	u16 fs_dmask_inv;
9862306a36Sopenharmony_ci
9962306a36Sopenharmony_ci	unsigned fmask : 1; /* fmask was set. */
10062306a36Sopenharmony_ci	unsigned dmask : 1; /*dmask was set. */
10162306a36Sopenharmony_ci	unsigned sys_immutable : 1; /* Immutable system files. */
10262306a36Sopenharmony_ci	unsigned discard : 1; /* Issue discard requests on deletions. */
10362306a36Sopenharmony_ci	unsigned sparse : 1; /* Create sparse files. */
10462306a36Sopenharmony_ci	unsigned showmeta : 1; /* Show meta files. */
10562306a36Sopenharmony_ci	unsigned nohidden : 1; /* Do not show hidden files. */
10662306a36Sopenharmony_ci	unsigned hide_dot_files : 1; /* Set hidden flag on dot files. */
10762306a36Sopenharmony_ci	unsigned windows_names : 1; /* Disallow names forbidden by Windows. */
10862306a36Sopenharmony_ci	unsigned force : 1; /* RW mount dirty volume. */
10962306a36Sopenharmony_ci	unsigned prealloc : 1; /* Preallocate space when file is growing. */
11062306a36Sopenharmony_ci	unsigned nocase : 1; /* case insensitive. */
11162306a36Sopenharmony_ci};
11262306a36Sopenharmony_ci
11362306a36Sopenharmony_ci/* Special value to unpack and deallocate. */
11462306a36Sopenharmony_ci#define RUN_DEALLOCATE ((struct runs_tree *)(size_t)1)
11562306a36Sopenharmony_ci
11662306a36Sopenharmony_ci/* TODO: Use rb tree instead of array. */
11762306a36Sopenharmony_cistruct runs_tree {
11862306a36Sopenharmony_ci	struct ntfs_run *runs;
11962306a36Sopenharmony_ci	size_t count; /* Currently used size a ntfs_run storage. */
12062306a36Sopenharmony_ci	size_t allocated; /* Currently allocated ntfs_run storage size. */
12162306a36Sopenharmony_ci};
12262306a36Sopenharmony_ci
12362306a36Sopenharmony_cistruct ntfs_buffers {
12462306a36Sopenharmony_ci	/* Biggest MFT / smallest cluster = 4096 / 512 = 8 */
12562306a36Sopenharmony_ci	/* Biggest index / smallest cluster = 4096 / 512 = 8 */
12662306a36Sopenharmony_ci	struct buffer_head *bh[PAGE_SIZE >> SECTOR_SHIFT];
12762306a36Sopenharmony_ci	u32 bytes;
12862306a36Sopenharmony_ci	u32 nbufs;
12962306a36Sopenharmony_ci	u32 off;
13062306a36Sopenharmony_ci};
13162306a36Sopenharmony_ci
13262306a36Sopenharmony_cienum ALLOCATE_OPT {
13362306a36Sopenharmony_ci	ALLOCATE_DEF = 0, // Allocate all clusters.
13462306a36Sopenharmony_ci	ALLOCATE_MFT = 1, // Allocate for MFT.
13562306a36Sopenharmony_ci	ALLOCATE_ZERO = 2, // Zeroout new allocated clusters
13662306a36Sopenharmony_ci};
13762306a36Sopenharmony_ci
13862306a36Sopenharmony_cienum bitmap_mutex_classes {
13962306a36Sopenharmony_ci	BITMAP_MUTEX_CLUSTERS = 0,
14062306a36Sopenharmony_ci	BITMAP_MUTEX_MFT = 1,
14162306a36Sopenharmony_ci};
14262306a36Sopenharmony_ci
14362306a36Sopenharmony_cistruct wnd_bitmap {
14462306a36Sopenharmony_ci	struct super_block *sb;
14562306a36Sopenharmony_ci	struct rw_semaphore rw_lock;
14662306a36Sopenharmony_ci
14762306a36Sopenharmony_ci	struct runs_tree run;
14862306a36Sopenharmony_ci	size_t nbits;
14962306a36Sopenharmony_ci
15062306a36Sopenharmony_ci	size_t total_zeroes; // Total number of free bits.
15162306a36Sopenharmony_ci	u16 *free_bits; // Free bits in each window.
15262306a36Sopenharmony_ci	size_t nwnd;
15362306a36Sopenharmony_ci	u32 bits_last; // Bits in last window.
15462306a36Sopenharmony_ci
15562306a36Sopenharmony_ci	struct rb_root start_tree; // Extents, sorted by 'start'.
15662306a36Sopenharmony_ci	struct rb_root count_tree; // Extents, sorted by 'count + start'.
15762306a36Sopenharmony_ci	size_t count; // Extents count.
15862306a36Sopenharmony_ci
15962306a36Sopenharmony_ci	/*
16062306a36Sopenharmony_ci	 * -1 Tree is activated but not updated (too many fragments).
16162306a36Sopenharmony_ci	 * 0 - Tree is not activated.
16262306a36Sopenharmony_ci	 * 1 - Tree is activated and updated.
16362306a36Sopenharmony_ci	 */
16462306a36Sopenharmony_ci	int uptodated;
16562306a36Sopenharmony_ci	size_t extent_min; // Minimal extent used while building.
16662306a36Sopenharmony_ci	size_t extent_max; // Upper estimate of biggest free block.
16762306a36Sopenharmony_ci
16862306a36Sopenharmony_ci	/* Zone [bit, end) */
16962306a36Sopenharmony_ci	size_t zone_bit;
17062306a36Sopenharmony_ci	size_t zone_end;
17162306a36Sopenharmony_ci
17262306a36Sopenharmony_ci	bool inited;
17362306a36Sopenharmony_ci};
17462306a36Sopenharmony_ci
17562306a36Sopenharmony_citypedef int (*NTFS_CMP_FUNC)(const void *key1, size_t len1, const void *key2,
17662306a36Sopenharmony_ci			     size_t len2, const void *param);
17762306a36Sopenharmony_ci
17862306a36Sopenharmony_cienum index_mutex_classed {
17962306a36Sopenharmony_ci	INDEX_MUTEX_I30 = 0,
18062306a36Sopenharmony_ci	INDEX_MUTEX_SII = 1,
18162306a36Sopenharmony_ci	INDEX_MUTEX_SDH = 2,
18262306a36Sopenharmony_ci	INDEX_MUTEX_SO = 3,
18362306a36Sopenharmony_ci	INDEX_MUTEX_SQ = 4,
18462306a36Sopenharmony_ci	INDEX_MUTEX_SR = 5,
18562306a36Sopenharmony_ci	INDEX_MUTEX_TOTAL
18662306a36Sopenharmony_ci};
18762306a36Sopenharmony_ci
18862306a36Sopenharmony_ci/* ntfs_index - Allocation unit inside directory. */
18962306a36Sopenharmony_cistruct ntfs_index {
19062306a36Sopenharmony_ci	struct runs_tree bitmap_run;
19162306a36Sopenharmony_ci	struct runs_tree alloc_run;
19262306a36Sopenharmony_ci	/* read/write access to 'bitmap_run'/'alloc_run' while ntfs_readdir */
19362306a36Sopenharmony_ci	struct rw_semaphore run_lock;
19462306a36Sopenharmony_ci
19562306a36Sopenharmony_ci	/*TODO: Remove 'cmp'. */
19662306a36Sopenharmony_ci	NTFS_CMP_FUNC cmp;
19762306a36Sopenharmony_ci
19862306a36Sopenharmony_ci	u8 index_bits; // log2(root->index_block_size)
19962306a36Sopenharmony_ci	u8 idx2vbn_bits; // log2(root->index_block_clst)
20062306a36Sopenharmony_ci	u8 vbn2vbo_bits; // index_block_size < cluster? 9 : cluster_bits
20162306a36Sopenharmony_ci	u8 type; // index_mutex_classed
20262306a36Sopenharmony_ci};
20362306a36Sopenharmony_ci
20462306a36Sopenharmony_ci/* Minimum MFT zone. */
20562306a36Sopenharmony_ci#define NTFS_MIN_MFT_ZONE 100
20662306a36Sopenharmony_ci/* Step to increase the MFT. */
20762306a36Sopenharmony_ci#define NTFS_MFT_INCREASE_STEP 1024
20862306a36Sopenharmony_ci
20962306a36Sopenharmony_ci/* Ntfs file system in-core superblock data. */
21062306a36Sopenharmony_cistruct ntfs_sb_info {
21162306a36Sopenharmony_ci	struct super_block *sb;
21262306a36Sopenharmony_ci
21362306a36Sopenharmony_ci	u32 discard_granularity;
21462306a36Sopenharmony_ci	u64 discard_granularity_mask_inv; // ~(discard_granularity_mask_inv-1)
21562306a36Sopenharmony_ci
21662306a36Sopenharmony_ci	u32 cluster_size; // bytes per cluster
21762306a36Sopenharmony_ci	u32 cluster_mask; // == cluster_size - 1
21862306a36Sopenharmony_ci	u64 cluster_mask_inv; // ~(cluster_size - 1)
21962306a36Sopenharmony_ci	u32 block_mask; // sb->s_blocksize - 1
22062306a36Sopenharmony_ci	u32 blocks_per_cluster; // cluster_size / sb->s_blocksize
22162306a36Sopenharmony_ci
22262306a36Sopenharmony_ci	u32 record_size;
22362306a36Sopenharmony_ci	u32 index_size;
22462306a36Sopenharmony_ci
22562306a36Sopenharmony_ci	u8 cluster_bits;
22662306a36Sopenharmony_ci	u8 record_bits;
22762306a36Sopenharmony_ci
22862306a36Sopenharmony_ci	u64 maxbytes; // Maximum size for normal files.
22962306a36Sopenharmony_ci	u64 maxbytes_sparse; // Maximum size for sparse file.
23062306a36Sopenharmony_ci
23162306a36Sopenharmony_ci	unsigned long flags; // See NTFS_FLAGS_
23262306a36Sopenharmony_ci
23362306a36Sopenharmony_ci	CLST zone_max; // Maximum MFT zone length in clusters
23462306a36Sopenharmony_ci	CLST bad_clusters; // The count of marked bad clusters.
23562306a36Sopenharmony_ci
23662306a36Sopenharmony_ci	u16 max_bytes_per_attr; // Maximum attribute size in record.
23762306a36Sopenharmony_ci	u16 attr_size_tr; // Attribute size threshold (320 bytes).
23862306a36Sopenharmony_ci
23962306a36Sopenharmony_ci	/* Records in $Extend. */
24062306a36Sopenharmony_ci	CLST objid_no;
24162306a36Sopenharmony_ci	CLST quota_no;
24262306a36Sopenharmony_ci	CLST reparse_no;
24362306a36Sopenharmony_ci	CLST usn_jrnl_no;
24462306a36Sopenharmony_ci
24562306a36Sopenharmony_ci	struct ATTR_DEF_ENTRY *def_table; // Attribute definition table.
24662306a36Sopenharmony_ci	u32 def_entries;
24762306a36Sopenharmony_ci	u32 ea_max_size;
24862306a36Sopenharmony_ci
24962306a36Sopenharmony_ci	struct MFT_REC *new_rec;
25062306a36Sopenharmony_ci
25162306a36Sopenharmony_ci	u16 *upcase;
25262306a36Sopenharmony_ci
25362306a36Sopenharmony_ci	struct {
25462306a36Sopenharmony_ci		u64 lbo, lbo2;
25562306a36Sopenharmony_ci		struct ntfs_inode *ni;
25662306a36Sopenharmony_ci		struct wnd_bitmap bitmap; // $MFT::Bitmap
25762306a36Sopenharmony_ci		/*
25862306a36Sopenharmony_ci		 * MFT records [11-24) used to expand MFT itself.
25962306a36Sopenharmony_ci		 * They always marked as used in $MFT::Bitmap
26062306a36Sopenharmony_ci		 * 'reserved_bitmap' contains real bitmap of these records.
26162306a36Sopenharmony_ci		 */
26262306a36Sopenharmony_ci		ulong reserved_bitmap; // Bitmap of used records [11 - 24)
26362306a36Sopenharmony_ci		size_t next_free; // The next record to allocate from
26462306a36Sopenharmony_ci		size_t used; // MFT valid size in records.
26562306a36Sopenharmony_ci		u32 recs_mirr; // Number of records in MFTMirr
26662306a36Sopenharmony_ci		u8 next_reserved;
26762306a36Sopenharmony_ci		u8 reserved_bitmap_inited;
26862306a36Sopenharmony_ci	} mft;
26962306a36Sopenharmony_ci
27062306a36Sopenharmony_ci	struct {
27162306a36Sopenharmony_ci		struct wnd_bitmap bitmap; // $Bitmap::Data
27262306a36Sopenharmony_ci		CLST next_free_lcn;
27362306a36Sopenharmony_ci	} used;
27462306a36Sopenharmony_ci
27562306a36Sopenharmony_ci	struct {
27662306a36Sopenharmony_ci		u64 size; // In bytes.
27762306a36Sopenharmony_ci		u64 blocks; // In blocks.
27862306a36Sopenharmony_ci		u64 ser_num;
27962306a36Sopenharmony_ci		struct ntfs_inode *ni;
28062306a36Sopenharmony_ci		__le16 flags; // Cached current VOLUME_INFO::flags, VOLUME_FLAG_DIRTY.
28162306a36Sopenharmony_ci		u8 major_ver;
28262306a36Sopenharmony_ci		u8 minor_ver;
28362306a36Sopenharmony_ci		char label[256];
28462306a36Sopenharmony_ci		bool real_dirty; // Real fs state.
28562306a36Sopenharmony_ci	} volume;
28662306a36Sopenharmony_ci
28762306a36Sopenharmony_ci	struct {
28862306a36Sopenharmony_ci		struct ntfs_index index_sii;
28962306a36Sopenharmony_ci		struct ntfs_index index_sdh;
29062306a36Sopenharmony_ci		struct ntfs_inode *ni;
29162306a36Sopenharmony_ci		u32 next_id;
29262306a36Sopenharmony_ci		u64 next_off;
29362306a36Sopenharmony_ci		__le32 def_security_id;
29462306a36Sopenharmony_ci	} security;
29562306a36Sopenharmony_ci
29662306a36Sopenharmony_ci	struct {
29762306a36Sopenharmony_ci		struct ntfs_index index_r;
29862306a36Sopenharmony_ci		struct ntfs_inode *ni;
29962306a36Sopenharmony_ci		u64 max_size; // 16K
30062306a36Sopenharmony_ci	} reparse;
30162306a36Sopenharmony_ci
30262306a36Sopenharmony_ci	struct {
30362306a36Sopenharmony_ci		struct ntfs_index index_o;
30462306a36Sopenharmony_ci		struct ntfs_inode *ni;
30562306a36Sopenharmony_ci	} objid;
30662306a36Sopenharmony_ci
30762306a36Sopenharmony_ci	struct {
30862306a36Sopenharmony_ci		struct mutex mtx_lznt;
30962306a36Sopenharmony_ci		struct lznt *lznt;
31062306a36Sopenharmony_ci#ifdef CONFIG_NTFS3_LZX_XPRESS
31162306a36Sopenharmony_ci		struct mutex mtx_xpress;
31262306a36Sopenharmony_ci		struct xpress_decompressor *xpress;
31362306a36Sopenharmony_ci		struct mutex mtx_lzx;
31462306a36Sopenharmony_ci		struct lzx_decompressor *lzx;
31562306a36Sopenharmony_ci#endif
31662306a36Sopenharmony_ci	} compress;
31762306a36Sopenharmony_ci
31862306a36Sopenharmony_ci	struct ntfs_mount_options *options;
31962306a36Sopenharmony_ci	struct ratelimit_state msg_ratelimit;
32062306a36Sopenharmony_ci	struct proc_dir_entry *procdir;
32162306a36Sopenharmony_ci};
32262306a36Sopenharmony_ci
32362306a36Sopenharmony_ci/* One MFT record(usually 1024 bytes), consists of attributes. */
32462306a36Sopenharmony_cistruct mft_inode {
32562306a36Sopenharmony_ci	struct rb_node node;
32662306a36Sopenharmony_ci	struct ntfs_sb_info *sbi;
32762306a36Sopenharmony_ci
32862306a36Sopenharmony_ci	struct MFT_REC *mrec;
32962306a36Sopenharmony_ci	struct ntfs_buffers nb;
33062306a36Sopenharmony_ci
33162306a36Sopenharmony_ci	CLST rno;
33262306a36Sopenharmony_ci	bool dirty;
33362306a36Sopenharmony_ci};
33462306a36Sopenharmony_ci
33562306a36Sopenharmony_ci/* Nested class for ntfs_inode::ni_lock. */
33662306a36Sopenharmony_cienum ntfs_inode_mutex_lock_class {
33762306a36Sopenharmony_ci	NTFS_INODE_MUTEX_DIRTY,
33862306a36Sopenharmony_ci	NTFS_INODE_MUTEX_SECURITY,
33962306a36Sopenharmony_ci	NTFS_INODE_MUTEX_OBJID,
34062306a36Sopenharmony_ci	NTFS_INODE_MUTEX_REPARSE,
34162306a36Sopenharmony_ci	NTFS_INODE_MUTEX_NORMAL,
34262306a36Sopenharmony_ci	NTFS_INODE_MUTEX_PARENT,
34362306a36Sopenharmony_ci	NTFS_INODE_MUTEX_PARENT2,
34462306a36Sopenharmony_ci};
34562306a36Sopenharmony_ci
34662306a36Sopenharmony_ci/*
34762306a36Sopenharmony_ci * struct ntfs_inode
34862306a36Sopenharmony_ci *
34962306a36Sopenharmony_ci * Ntfs inode - extends linux inode. consists of one or more MFT inodes.
35062306a36Sopenharmony_ci */
35162306a36Sopenharmony_cistruct ntfs_inode {
35262306a36Sopenharmony_ci	struct mft_inode mi; // base record
35362306a36Sopenharmony_ci
35462306a36Sopenharmony_ci	/*
35562306a36Sopenharmony_ci	 * Valid size: [0 - i_valid) - these range in file contains valid data.
35662306a36Sopenharmony_ci	 * Range [i_valid - inode->i_size) - contains 0.
35762306a36Sopenharmony_ci	 * Usually i_valid <= inode->i_size.
35862306a36Sopenharmony_ci	 */
35962306a36Sopenharmony_ci	u64 i_valid;
36062306a36Sopenharmony_ci	struct timespec64 i_crtime;
36162306a36Sopenharmony_ci
36262306a36Sopenharmony_ci	struct mutex ni_lock;
36362306a36Sopenharmony_ci
36462306a36Sopenharmony_ci	/* File attributes from std. */
36562306a36Sopenharmony_ci	enum FILE_ATTRIBUTE std_fa;
36662306a36Sopenharmony_ci	__le32 std_security_id;
36762306a36Sopenharmony_ci
36862306a36Sopenharmony_ci	/*
36962306a36Sopenharmony_ci	 * Tree of mft_inode.
37062306a36Sopenharmony_ci	 * Not empty when primary MFT record (usually 1024 bytes) can't save all attributes
37162306a36Sopenharmony_ci	 * e.g. file becomes too fragmented or contains a lot of names.
37262306a36Sopenharmony_ci	 */
37362306a36Sopenharmony_ci	struct rb_root mi_tree;
37462306a36Sopenharmony_ci
37562306a36Sopenharmony_ci	/*
37662306a36Sopenharmony_ci	 * This member is used in ntfs_readdir to ensure that all subrecords are loaded
37762306a36Sopenharmony_ci	 */
37862306a36Sopenharmony_ci	u8 mi_loaded;
37962306a36Sopenharmony_ci
38062306a36Sopenharmony_ci	union {
38162306a36Sopenharmony_ci		struct ntfs_index dir;
38262306a36Sopenharmony_ci		struct {
38362306a36Sopenharmony_ci			struct rw_semaphore run_lock;
38462306a36Sopenharmony_ci			struct runs_tree run;
38562306a36Sopenharmony_ci#ifdef CONFIG_NTFS3_LZX_XPRESS
38662306a36Sopenharmony_ci			struct page *offs_page;
38762306a36Sopenharmony_ci#endif
38862306a36Sopenharmony_ci		} file;
38962306a36Sopenharmony_ci	};
39062306a36Sopenharmony_ci
39162306a36Sopenharmony_ci	struct {
39262306a36Sopenharmony_ci		struct runs_tree run;
39362306a36Sopenharmony_ci		struct ATTR_LIST_ENTRY *le; // 1K aligned memory.
39462306a36Sopenharmony_ci		size_t size;
39562306a36Sopenharmony_ci		bool dirty;
39662306a36Sopenharmony_ci	} attr_list;
39762306a36Sopenharmony_ci
39862306a36Sopenharmony_ci	size_t ni_flags; // NI_FLAG_XXX
39962306a36Sopenharmony_ci
40062306a36Sopenharmony_ci	struct inode vfs_inode;
40162306a36Sopenharmony_ci};
40262306a36Sopenharmony_ci
40362306a36Sopenharmony_cistruct indx_node {
40462306a36Sopenharmony_ci	struct ntfs_buffers nb;
40562306a36Sopenharmony_ci	struct INDEX_BUFFER *index;
40662306a36Sopenharmony_ci};
40762306a36Sopenharmony_ci
40862306a36Sopenharmony_cistruct ntfs_fnd {
40962306a36Sopenharmony_ci	int level;
41062306a36Sopenharmony_ci	struct indx_node *nodes[20];
41162306a36Sopenharmony_ci	struct NTFS_DE *de[20];
41262306a36Sopenharmony_ci	struct NTFS_DE *root_de;
41362306a36Sopenharmony_ci};
41462306a36Sopenharmony_ci
41562306a36Sopenharmony_cienum REPARSE_SIGN {
41662306a36Sopenharmony_ci	REPARSE_NONE = 0,
41762306a36Sopenharmony_ci	REPARSE_COMPRESSED = 1,
41862306a36Sopenharmony_ci	REPARSE_DEDUPLICATED = 2,
41962306a36Sopenharmony_ci	REPARSE_LINK = 3
42062306a36Sopenharmony_ci};
42162306a36Sopenharmony_ci
42262306a36Sopenharmony_ci/* Functions from attrib.c */
42362306a36Sopenharmony_ciint attr_allocate_clusters(struct ntfs_sb_info *sbi, struct runs_tree *run,
42462306a36Sopenharmony_ci			   CLST vcn, CLST lcn, CLST len, CLST *pre_alloc,
42562306a36Sopenharmony_ci			   enum ALLOCATE_OPT opt, CLST *alen, const size_t fr,
42662306a36Sopenharmony_ci			   CLST *new_lcn, CLST *new_len);
42762306a36Sopenharmony_ciint attr_make_nonresident(struct ntfs_inode *ni, struct ATTRIB *attr,
42862306a36Sopenharmony_ci			  struct ATTR_LIST_ENTRY *le, struct mft_inode *mi,
42962306a36Sopenharmony_ci			  u64 new_size, struct runs_tree *run,
43062306a36Sopenharmony_ci			  struct ATTRIB **ins_attr, struct page *page);
43162306a36Sopenharmony_ciint attr_set_size(struct ntfs_inode *ni, enum ATTR_TYPE type,
43262306a36Sopenharmony_ci		  const __le16 *name, u8 name_len, struct runs_tree *run,
43362306a36Sopenharmony_ci		  u64 new_size, const u64 *new_valid, bool keep_prealloc,
43462306a36Sopenharmony_ci		  struct ATTRIB **ret);
43562306a36Sopenharmony_ciint attr_data_get_block(struct ntfs_inode *ni, CLST vcn, CLST clen, CLST *lcn,
43662306a36Sopenharmony_ci			CLST *len, bool *new, bool zero);
43762306a36Sopenharmony_ciint attr_data_read_resident(struct ntfs_inode *ni, struct page *page);
43862306a36Sopenharmony_ciint attr_data_write_resident(struct ntfs_inode *ni, struct page *page);
43962306a36Sopenharmony_ciint attr_load_runs_vcn(struct ntfs_inode *ni, enum ATTR_TYPE type,
44062306a36Sopenharmony_ci		       const __le16 *name, u8 name_len, struct runs_tree *run,
44162306a36Sopenharmony_ci		       CLST vcn);
44262306a36Sopenharmony_ciint attr_load_runs_range(struct ntfs_inode *ni, enum ATTR_TYPE type,
44362306a36Sopenharmony_ci			 const __le16 *name, u8 name_len, struct runs_tree *run,
44462306a36Sopenharmony_ci			 u64 from, u64 to);
44562306a36Sopenharmony_ciint attr_wof_frame_info(struct ntfs_inode *ni, struct ATTRIB *attr,
44662306a36Sopenharmony_ci			struct runs_tree *run, u64 frame, u64 frames,
44762306a36Sopenharmony_ci			u8 frame_bits, u32 *ondisk_size, u64 *vbo_data);
44862306a36Sopenharmony_ciint attr_is_frame_compressed(struct ntfs_inode *ni, struct ATTRIB *attr,
44962306a36Sopenharmony_ci			     CLST frame, CLST *clst_data);
45062306a36Sopenharmony_ciint attr_allocate_frame(struct ntfs_inode *ni, CLST frame, size_t compr_size,
45162306a36Sopenharmony_ci			u64 new_valid);
45262306a36Sopenharmony_ciint attr_collapse_range(struct ntfs_inode *ni, u64 vbo, u64 bytes);
45362306a36Sopenharmony_ciint attr_insert_range(struct ntfs_inode *ni, u64 vbo, u64 bytes);
45462306a36Sopenharmony_ciint attr_punch_hole(struct ntfs_inode *ni, u64 vbo, u64 bytes, u32 *frame_size);
45562306a36Sopenharmony_ci
45662306a36Sopenharmony_ci/* Functions from attrlist.c */
45762306a36Sopenharmony_civoid al_destroy(struct ntfs_inode *ni);
45862306a36Sopenharmony_cibool al_verify(struct ntfs_inode *ni);
45962306a36Sopenharmony_ciint ntfs_load_attr_list(struct ntfs_inode *ni, struct ATTRIB *attr);
46062306a36Sopenharmony_cistruct ATTR_LIST_ENTRY *al_enumerate(struct ntfs_inode *ni,
46162306a36Sopenharmony_ci				     struct ATTR_LIST_ENTRY *le);
46262306a36Sopenharmony_cistruct ATTR_LIST_ENTRY *al_find_le(struct ntfs_inode *ni,
46362306a36Sopenharmony_ci				   struct ATTR_LIST_ENTRY *le,
46462306a36Sopenharmony_ci				   const struct ATTRIB *attr);
46562306a36Sopenharmony_cistruct ATTR_LIST_ENTRY *al_find_ex(struct ntfs_inode *ni,
46662306a36Sopenharmony_ci				   struct ATTR_LIST_ENTRY *le,
46762306a36Sopenharmony_ci				   enum ATTR_TYPE type, const __le16 *name,
46862306a36Sopenharmony_ci				   u8 name_len, const CLST *vcn);
46962306a36Sopenharmony_ciint al_add_le(struct ntfs_inode *ni, enum ATTR_TYPE type, const __le16 *name,
47062306a36Sopenharmony_ci	      u8 name_len, CLST svcn, __le16 id, const struct MFT_REF *ref,
47162306a36Sopenharmony_ci	      struct ATTR_LIST_ENTRY **new_le);
47262306a36Sopenharmony_cibool al_remove_le(struct ntfs_inode *ni, struct ATTR_LIST_ENTRY *le);
47362306a36Sopenharmony_cibool al_delete_le(struct ntfs_inode *ni, enum ATTR_TYPE type, CLST vcn,
47462306a36Sopenharmony_ci		  const __le16 *name, u8 name_len, const struct MFT_REF *ref);
47562306a36Sopenharmony_ciint al_update(struct ntfs_inode *ni, int sync);
47662306a36Sopenharmony_cistatic inline size_t al_aligned(size_t size)
47762306a36Sopenharmony_ci{
47862306a36Sopenharmony_ci	return size_add(size, 1023) & ~(size_t)1023;
47962306a36Sopenharmony_ci}
48062306a36Sopenharmony_ci
48162306a36Sopenharmony_ci/* Globals from bitfunc.c */
48262306a36Sopenharmony_cibool are_bits_clear(const void *map, size_t bit, size_t nbits);
48362306a36Sopenharmony_cibool are_bits_set(const void *map, size_t bit, size_t nbits);
48462306a36Sopenharmony_cisize_t get_set_bits_ex(const void *map, size_t bit, size_t nbits);
48562306a36Sopenharmony_ci
48662306a36Sopenharmony_ci/* Globals from dir.c */
48762306a36Sopenharmony_ciint ntfs_utf16_to_nls(struct ntfs_sb_info *sbi, const __le16 *name, u32 len,
48862306a36Sopenharmony_ci		      u8 *buf, int buf_len);
48962306a36Sopenharmony_ciint ntfs_nls_to_utf16(struct ntfs_sb_info *sbi, const u8 *name, u32 name_len,
49062306a36Sopenharmony_ci		      struct cpu_str *uni, u32 max_ulen,
49162306a36Sopenharmony_ci		      enum utf16_endian endian);
49262306a36Sopenharmony_cistruct inode *dir_search_u(struct inode *dir, const struct cpu_str *uni,
49362306a36Sopenharmony_ci			   struct ntfs_fnd *fnd);
49462306a36Sopenharmony_cibool dir_is_empty(struct inode *dir);
49562306a36Sopenharmony_ciextern const struct file_operations ntfs_dir_operations;
49662306a36Sopenharmony_ci
49762306a36Sopenharmony_ci/* Globals from file.c */
49862306a36Sopenharmony_ciint ntfs_getattr(struct mnt_idmap *idmap, const struct path *path,
49962306a36Sopenharmony_ci		 struct kstat *stat, u32 request_mask, u32 flags);
50062306a36Sopenharmony_ciint ntfs3_setattr(struct mnt_idmap *idmap, struct dentry *dentry,
50162306a36Sopenharmony_ci		  struct iattr *attr);
50262306a36Sopenharmony_ciint ntfs_file_open(struct inode *inode, struct file *file);
50362306a36Sopenharmony_ciint ntfs_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
50462306a36Sopenharmony_ci		__u64 start, __u64 len);
50562306a36Sopenharmony_ciextern const struct inode_operations ntfs_special_inode_operations;
50662306a36Sopenharmony_ciextern const struct inode_operations ntfs_file_inode_operations;
50762306a36Sopenharmony_ciextern const struct file_operations ntfs_file_operations;
50862306a36Sopenharmony_ci
50962306a36Sopenharmony_ci/* Globals from frecord.c */
51062306a36Sopenharmony_civoid ni_remove_mi(struct ntfs_inode *ni, struct mft_inode *mi);
51162306a36Sopenharmony_cistruct ATTR_STD_INFO *ni_std(struct ntfs_inode *ni);
51262306a36Sopenharmony_cistruct ATTR_STD_INFO5 *ni_std5(struct ntfs_inode *ni);
51362306a36Sopenharmony_civoid ni_clear(struct ntfs_inode *ni);
51462306a36Sopenharmony_ciint ni_load_mi_ex(struct ntfs_inode *ni, CLST rno, struct mft_inode **mi);
51562306a36Sopenharmony_ciint ni_load_mi(struct ntfs_inode *ni, const struct ATTR_LIST_ENTRY *le,
51662306a36Sopenharmony_ci	       struct mft_inode **mi);
51762306a36Sopenharmony_cistruct ATTRIB *ni_find_attr(struct ntfs_inode *ni, struct ATTRIB *attr,
51862306a36Sopenharmony_ci			    struct ATTR_LIST_ENTRY **entry_o,
51962306a36Sopenharmony_ci			    enum ATTR_TYPE type, const __le16 *name,
52062306a36Sopenharmony_ci			    u8 name_len, const CLST *vcn,
52162306a36Sopenharmony_ci			    struct mft_inode **mi);
52262306a36Sopenharmony_cistruct ATTRIB *ni_enum_attr_ex(struct ntfs_inode *ni, struct ATTRIB *attr,
52362306a36Sopenharmony_ci			       struct ATTR_LIST_ENTRY **le,
52462306a36Sopenharmony_ci			       struct mft_inode **mi);
52562306a36Sopenharmony_cistruct ATTRIB *ni_load_attr(struct ntfs_inode *ni, enum ATTR_TYPE type,
52662306a36Sopenharmony_ci			    const __le16 *name, u8 name_len, CLST vcn,
52762306a36Sopenharmony_ci			    struct mft_inode **pmi);
52862306a36Sopenharmony_ciint ni_load_all_mi(struct ntfs_inode *ni);
52962306a36Sopenharmony_cibool ni_add_subrecord(struct ntfs_inode *ni, CLST rno, struct mft_inode **mi);
53062306a36Sopenharmony_ciint ni_remove_attr(struct ntfs_inode *ni, enum ATTR_TYPE type,
53162306a36Sopenharmony_ci		   const __le16 *name, u8 name_len, bool base_only,
53262306a36Sopenharmony_ci		   const __le16 *id);
53362306a36Sopenharmony_ciint ni_create_attr_list(struct ntfs_inode *ni);
53462306a36Sopenharmony_ciint ni_expand_list(struct ntfs_inode *ni);
53562306a36Sopenharmony_ciint ni_insert_nonresident(struct ntfs_inode *ni, enum ATTR_TYPE type,
53662306a36Sopenharmony_ci			  const __le16 *name, u8 name_len,
53762306a36Sopenharmony_ci			  const struct runs_tree *run, CLST svcn, CLST len,
53862306a36Sopenharmony_ci			  __le16 flags, struct ATTRIB **new_attr,
53962306a36Sopenharmony_ci			  struct mft_inode **mi, struct ATTR_LIST_ENTRY **le);
54062306a36Sopenharmony_ciint ni_insert_resident(struct ntfs_inode *ni, u32 data_size,
54162306a36Sopenharmony_ci		       enum ATTR_TYPE type, const __le16 *name, u8 name_len,
54262306a36Sopenharmony_ci		       struct ATTRIB **new_attr, struct mft_inode **mi,
54362306a36Sopenharmony_ci		       struct ATTR_LIST_ENTRY **le);
54462306a36Sopenharmony_civoid ni_remove_attr_le(struct ntfs_inode *ni, struct ATTRIB *attr,
54562306a36Sopenharmony_ci		       struct mft_inode *mi, struct ATTR_LIST_ENTRY *le);
54662306a36Sopenharmony_ciint ni_delete_all(struct ntfs_inode *ni);
54762306a36Sopenharmony_cistruct ATTR_FILE_NAME *ni_fname_name(struct ntfs_inode *ni,
54862306a36Sopenharmony_ci				     const struct le_str *uni,
54962306a36Sopenharmony_ci				     const struct MFT_REF *home,
55062306a36Sopenharmony_ci				     struct mft_inode **mi,
55162306a36Sopenharmony_ci				     struct ATTR_LIST_ENTRY **entry);
55262306a36Sopenharmony_cistruct ATTR_FILE_NAME *ni_fname_type(struct ntfs_inode *ni, u8 name_type,
55362306a36Sopenharmony_ci				     struct mft_inode **mi,
55462306a36Sopenharmony_ci				     struct ATTR_LIST_ENTRY **entry);
55562306a36Sopenharmony_ciint ni_new_attr_flags(struct ntfs_inode *ni, enum FILE_ATTRIBUTE new_fa);
55662306a36Sopenharmony_cienum REPARSE_SIGN ni_parse_reparse(struct ntfs_inode *ni, struct ATTRIB *attr,
55762306a36Sopenharmony_ci				   struct REPARSE_DATA_BUFFER *buffer);
55862306a36Sopenharmony_ciint ni_write_inode(struct inode *inode, int sync, const char *hint);
55962306a36Sopenharmony_ci#define _ni_write_inode(i, w) ni_write_inode(i, w, __func__)
56062306a36Sopenharmony_ciint ni_fiemap(struct ntfs_inode *ni, struct fiemap_extent_info *fieinfo,
56162306a36Sopenharmony_ci	      __u64 vbo, __u64 len);
56262306a36Sopenharmony_ciint ni_readpage_cmpr(struct ntfs_inode *ni, struct page *page);
56362306a36Sopenharmony_ciint ni_decompress_file(struct ntfs_inode *ni);
56462306a36Sopenharmony_ciint ni_read_frame(struct ntfs_inode *ni, u64 frame_vbo, struct page **pages,
56562306a36Sopenharmony_ci		  u32 pages_per_frame);
56662306a36Sopenharmony_ciint ni_write_frame(struct ntfs_inode *ni, struct page **pages,
56762306a36Sopenharmony_ci		   u32 pages_per_frame);
56862306a36Sopenharmony_ciint ni_remove_name(struct ntfs_inode *dir_ni, struct ntfs_inode *ni,
56962306a36Sopenharmony_ci		   struct NTFS_DE *de, struct NTFS_DE **de2, int *undo_step);
57062306a36Sopenharmony_ci
57162306a36Sopenharmony_cibool ni_remove_name_undo(struct ntfs_inode *dir_ni, struct ntfs_inode *ni,
57262306a36Sopenharmony_ci			 struct NTFS_DE *de, struct NTFS_DE *de2,
57362306a36Sopenharmony_ci			 int undo_step);
57462306a36Sopenharmony_ci
57562306a36Sopenharmony_ciint ni_add_name(struct ntfs_inode *dir_ni, struct ntfs_inode *ni,
57662306a36Sopenharmony_ci		struct NTFS_DE *de);
57762306a36Sopenharmony_ci
57862306a36Sopenharmony_ciint ni_rename(struct ntfs_inode *dir_ni, struct ntfs_inode *new_dir_ni,
57962306a36Sopenharmony_ci	      struct ntfs_inode *ni, struct NTFS_DE *de, struct NTFS_DE *new_de,
58062306a36Sopenharmony_ci	      bool *is_bad);
58162306a36Sopenharmony_ci
58262306a36Sopenharmony_cibool ni_is_dirty(struct inode *inode);
58362306a36Sopenharmony_ci
58462306a36Sopenharmony_ci/* Globals from fslog.c */
58562306a36Sopenharmony_cibool check_index_header(const struct INDEX_HDR *hdr, size_t bytes);
58662306a36Sopenharmony_ciint log_replay(struct ntfs_inode *ni, bool *initialized);
58762306a36Sopenharmony_ci
58862306a36Sopenharmony_ci/* Globals from fsntfs.c */
58962306a36Sopenharmony_cistruct buffer_head *ntfs_bread(struct super_block *sb, sector_t block);
59062306a36Sopenharmony_cibool ntfs_fix_pre_write(struct NTFS_RECORD_HEADER *rhdr, size_t bytes);
59162306a36Sopenharmony_ciint ntfs_fix_post_read(struct NTFS_RECORD_HEADER *rhdr, size_t bytes,
59262306a36Sopenharmony_ci		       bool simple);
59362306a36Sopenharmony_ciint ntfs_extend_init(struct ntfs_sb_info *sbi);
59462306a36Sopenharmony_ciint ntfs_loadlog_and_replay(struct ntfs_inode *ni, struct ntfs_sb_info *sbi);
59562306a36Sopenharmony_ciint ntfs_look_for_free_space(struct ntfs_sb_info *sbi, CLST lcn, CLST len,
59662306a36Sopenharmony_ci			     CLST *new_lcn, CLST *new_len,
59762306a36Sopenharmony_ci			     enum ALLOCATE_OPT opt);
59862306a36Sopenharmony_cibool ntfs_check_for_free_space(struct ntfs_sb_info *sbi, CLST clen, CLST mlen);
59962306a36Sopenharmony_ciint ntfs_look_free_mft(struct ntfs_sb_info *sbi, CLST *rno, bool mft,
60062306a36Sopenharmony_ci		       struct ntfs_inode *ni, struct mft_inode **mi);
60162306a36Sopenharmony_civoid ntfs_mark_rec_free(struct ntfs_sb_info *sbi, CLST rno, bool is_mft);
60262306a36Sopenharmony_ciint ntfs_clear_mft_tail(struct ntfs_sb_info *sbi, size_t from, size_t to);
60362306a36Sopenharmony_ciint ntfs_refresh_zone(struct ntfs_sb_info *sbi);
60462306a36Sopenharmony_civoid ntfs_update_mftmirr(struct ntfs_sb_info *sbi, int wait);
60562306a36Sopenharmony_civoid ntfs_bad_inode(struct inode *inode, const char *hint);
60662306a36Sopenharmony_ci#define _ntfs_bad_inode(i) ntfs_bad_inode(i, __func__)
60762306a36Sopenharmony_cienum NTFS_DIRTY_FLAGS {
60862306a36Sopenharmony_ci	NTFS_DIRTY_CLEAR = 0,
60962306a36Sopenharmony_ci	NTFS_DIRTY_DIRTY = 1,
61062306a36Sopenharmony_ci	NTFS_DIRTY_ERROR = 2,
61162306a36Sopenharmony_ci};
61262306a36Sopenharmony_ciint ntfs_set_state(struct ntfs_sb_info *sbi, enum NTFS_DIRTY_FLAGS dirty);
61362306a36Sopenharmony_ciint ntfs_sb_read(struct super_block *sb, u64 lbo, size_t bytes, void *buffer);
61462306a36Sopenharmony_ciint ntfs_sb_write(struct super_block *sb, u64 lbo, size_t bytes,
61562306a36Sopenharmony_ci		  const void *buffer, int wait);
61662306a36Sopenharmony_ciint ntfs_sb_write_run(struct ntfs_sb_info *sbi, const struct runs_tree *run,
61762306a36Sopenharmony_ci		      u64 vbo, const void *buf, size_t bytes, int sync);
61862306a36Sopenharmony_cistruct buffer_head *ntfs_bread_run(struct ntfs_sb_info *sbi,
61962306a36Sopenharmony_ci				   const struct runs_tree *run, u64 vbo);
62062306a36Sopenharmony_ciint ntfs_read_run_nb(struct ntfs_sb_info *sbi, const struct runs_tree *run,
62162306a36Sopenharmony_ci		     u64 vbo, void *buf, u32 bytes, struct ntfs_buffers *nb);
62262306a36Sopenharmony_ciint ntfs_read_bh(struct ntfs_sb_info *sbi, const struct runs_tree *run, u64 vbo,
62362306a36Sopenharmony_ci		 struct NTFS_RECORD_HEADER *rhdr, u32 bytes,
62462306a36Sopenharmony_ci		 struct ntfs_buffers *nb);
62562306a36Sopenharmony_ciint ntfs_get_bh(struct ntfs_sb_info *sbi, const struct runs_tree *run, u64 vbo,
62662306a36Sopenharmony_ci		u32 bytes, struct ntfs_buffers *nb);
62762306a36Sopenharmony_ciint ntfs_write_bh(struct ntfs_sb_info *sbi, struct NTFS_RECORD_HEADER *rhdr,
62862306a36Sopenharmony_ci		  struct ntfs_buffers *nb, int sync);
62962306a36Sopenharmony_ciint ntfs_bio_pages(struct ntfs_sb_info *sbi, const struct runs_tree *run,
63062306a36Sopenharmony_ci		   struct page **pages, u32 nr_pages, u64 vbo, u32 bytes,
63162306a36Sopenharmony_ci		   enum req_op op);
63262306a36Sopenharmony_ciint ntfs_bio_fill_1(struct ntfs_sb_info *sbi, const struct runs_tree *run);
63362306a36Sopenharmony_ciint ntfs_vbo_to_lbo(struct ntfs_sb_info *sbi, const struct runs_tree *run,
63462306a36Sopenharmony_ci		    u64 vbo, u64 *lbo, u64 *bytes);
63562306a36Sopenharmony_cistruct ntfs_inode *ntfs_new_inode(struct ntfs_sb_info *sbi, CLST nRec,
63662306a36Sopenharmony_ci				  enum RECORD_FLAG flag);
63762306a36Sopenharmony_ciextern const u8 s_default_security[0x50];
63862306a36Sopenharmony_cibool is_sd_valid(const struct SECURITY_DESCRIPTOR_RELATIVE *sd, u32 len);
63962306a36Sopenharmony_ciint ntfs_security_init(struct ntfs_sb_info *sbi);
64062306a36Sopenharmony_ciint ntfs_get_security_by_id(struct ntfs_sb_info *sbi, __le32 security_id,
64162306a36Sopenharmony_ci			    struct SECURITY_DESCRIPTOR_RELATIVE **sd,
64262306a36Sopenharmony_ci			    size_t *size);
64362306a36Sopenharmony_ciint ntfs_insert_security(struct ntfs_sb_info *sbi,
64462306a36Sopenharmony_ci			 const struct SECURITY_DESCRIPTOR_RELATIVE *sd,
64562306a36Sopenharmony_ci			 u32 size, __le32 *security_id, bool *inserted);
64662306a36Sopenharmony_ciint ntfs_reparse_init(struct ntfs_sb_info *sbi);
64762306a36Sopenharmony_ciint ntfs_objid_init(struct ntfs_sb_info *sbi);
64862306a36Sopenharmony_ciint ntfs_objid_remove(struct ntfs_sb_info *sbi, struct GUID *guid);
64962306a36Sopenharmony_ciint ntfs_insert_reparse(struct ntfs_sb_info *sbi, __le32 rtag,
65062306a36Sopenharmony_ci			const struct MFT_REF *ref);
65162306a36Sopenharmony_ciint ntfs_remove_reparse(struct ntfs_sb_info *sbi, __le32 rtag,
65262306a36Sopenharmony_ci			const struct MFT_REF *ref);
65362306a36Sopenharmony_civoid mark_as_free_ex(struct ntfs_sb_info *sbi, CLST lcn, CLST len, bool trim);
65462306a36Sopenharmony_ciint run_deallocate(struct ntfs_sb_info *sbi, const struct runs_tree *run,
65562306a36Sopenharmony_ci		   bool trim);
65662306a36Sopenharmony_cibool valid_windows_name(struct ntfs_sb_info *sbi, const struct le_str *name);
65762306a36Sopenharmony_ciint ntfs_set_label(struct ntfs_sb_info *sbi, u8 *label, int len);
65862306a36Sopenharmony_ci
65962306a36Sopenharmony_ci/* Globals from index.c */
66062306a36Sopenharmony_ciint indx_used_bit(struct ntfs_index *indx, struct ntfs_inode *ni, size_t *bit);
66162306a36Sopenharmony_civoid fnd_clear(struct ntfs_fnd *fnd);
66262306a36Sopenharmony_cistatic inline struct ntfs_fnd *fnd_get(void)
66362306a36Sopenharmony_ci{
66462306a36Sopenharmony_ci	return kzalloc(sizeof(struct ntfs_fnd), GFP_NOFS);
66562306a36Sopenharmony_ci}
66662306a36Sopenharmony_cistatic inline void fnd_put(struct ntfs_fnd *fnd)
66762306a36Sopenharmony_ci{
66862306a36Sopenharmony_ci	if (fnd) {
66962306a36Sopenharmony_ci		fnd_clear(fnd);
67062306a36Sopenharmony_ci		kfree(fnd);
67162306a36Sopenharmony_ci	}
67262306a36Sopenharmony_ci}
67362306a36Sopenharmony_civoid indx_clear(struct ntfs_index *idx);
67462306a36Sopenharmony_ciint indx_init(struct ntfs_index *indx, struct ntfs_sb_info *sbi,
67562306a36Sopenharmony_ci	      const struct ATTRIB *attr, enum index_mutex_classed type);
67662306a36Sopenharmony_cistruct INDEX_ROOT *indx_get_root(struct ntfs_index *indx, struct ntfs_inode *ni,
67762306a36Sopenharmony_ci				 struct ATTRIB **attr, struct mft_inode **mi);
67862306a36Sopenharmony_ciint indx_read(struct ntfs_index *idx, struct ntfs_inode *ni, CLST vbn,
67962306a36Sopenharmony_ci	      struct indx_node **node);
68062306a36Sopenharmony_ciint indx_find(struct ntfs_index *indx, struct ntfs_inode *dir,
68162306a36Sopenharmony_ci	      const struct INDEX_ROOT *root, const void *Key, size_t KeyLen,
68262306a36Sopenharmony_ci	      const void *param, int *diff, struct NTFS_DE **entry,
68362306a36Sopenharmony_ci	      struct ntfs_fnd *fnd);
68462306a36Sopenharmony_ciint indx_find_sort(struct ntfs_index *indx, struct ntfs_inode *ni,
68562306a36Sopenharmony_ci		   const struct INDEX_ROOT *root, struct NTFS_DE **entry,
68662306a36Sopenharmony_ci		   struct ntfs_fnd *fnd);
68762306a36Sopenharmony_ciint indx_find_raw(struct ntfs_index *indx, struct ntfs_inode *ni,
68862306a36Sopenharmony_ci		  const struct INDEX_ROOT *root, struct NTFS_DE **entry,
68962306a36Sopenharmony_ci		  size_t *off, struct ntfs_fnd *fnd);
69062306a36Sopenharmony_ciint indx_insert_entry(struct ntfs_index *indx, struct ntfs_inode *ni,
69162306a36Sopenharmony_ci		      const struct NTFS_DE *new_de, const void *param,
69262306a36Sopenharmony_ci		      struct ntfs_fnd *fnd, bool undo);
69362306a36Sopenharmony_ciint indx_delete_entry(struct ntfs_index *indx, struct ntfs_inode *ni,
69462306a36Sopenharmony_ci		      const void *key, u32 key_len, const void *param);
69562306a36Sopenharmony_ciint indx_update_dup(struct ntfs_inode *ni, struct ntfs_sb_info *sbi,
69662306a36Sopenharmony_ci		    const struct ATTR_FILE_NAME *fname,
69762306a36Sopenharmony_ci		    const struct NTFS_DUP_INFO *dup, int sync);
69862306a36Sopenharmony_ci
69962306a36Sopenharmony_ci/* Globals from inode.c */
70062306a36Sopenharmony_cistruct inode *ntfs_iget5(struct super_block *sb, const struct MFT_REF *ref,
70162306a36Sopenharmony_ci			 const struct cpu_str *name);
70262306a36Sopenharmony_ciint ntfs_set_size(struct inode *inode, u64 new_size);
70362306a36Sopenharmony_ciint reset_log_file(struct inode *inode);
70462306a36Sopenharmony_ciint ntfs_get_block(struct inode *inode, sector_t vbn,
70562306a36Sopenharmony_ci		   struct buffer_head *bh_result, int create);
70662306a36Sopenharmony_ciint ntfs_write_begin(struct file *file, struct address_space *mapping,
70762306a36Sopenharmony_ci		     loff_t pos, u32 len, struct page **pagep, void **fsdata);
70862306a36Sopenharmony_ciint ntfs_write_end(struct file *file, struct address_space *mapping, loff_t pos,
70962306a36Sopenharmony_ci		   u32 len, u32 copied, struct page *page, void *fsdata);
71062306a36Sopenharmony_ciint ntfs3_write_inode(struct inode *inode, struct writeback_control *wbc);
71162306a36Sopenharmony_ciint ntfs_sync_inode(struct inode *inode);
71262306a36Sopenharmony_ciint ntfs_flush_inodes(struct super_block *sb, struct inode *i1,
71362306a36Sopenharmony_ci		      struct inode *i2);
71462306a36Sopenharmony_ciint inode_write_data(struct inode *inode, const void *data, size_t bytes);
71562306a36Sopenharmony_cistruct inode *ntfs_create_inode(struct mnt_idmap *idmap, struct inode *dir,
71662306a36Sopenharmony_ci				struct dentry *dentry,
71762306a36Sopenharmony_ci				const struct cpu_str *uni, umode_t mode,
71862306a36Sopenharmony_ci				dev_t dev, const char *symname, u32 size,
71962306a36Sopenharmony_ci				struct ntfs_fnd *fnd);
72062306a36Sopenharmony_ciint ntfs_link_inode(struct inode *inode, struct dentry *dentry);
72162306a36Sopenharmony_ciint ntfs_unlink_inode(struct inode *dir, const struct dentry *dentry);
72262306a36Sopenharmony_civoid ntfs_evict_inode(struct inode *inode);
72362306a36Sopenharmony_ciextern const struct inode_operations ntfs_link_inode_operations;
72462306a36Sopenharmony_ciextern const struct address_space_operations ntfs_aops;
72562306a36Sopenharmony_ciextern const struct address_space_operations ntfs_aops_cmpr;
72662306a36Sopenharmony_ci
72762306a36Sopenharmony_ci/* Globals from name_i.c */
72862306a36Sopenharmony_ciint fill_name_de(struct ntfs_sb_info *sbi, void *buf, const struct qstr *name,
72962306a36Sopenharmony_ci		 const struct cpu_str *uni);
73062306a36Sopenharmony_cistruct dentry *ntfs3_get_parent(struct dentry *child);
73162306a36Sopenharmony_ci
73262306a36Sopenharmony_ciextern const struct inode_operations ntfs_dir_inode_operations;
73362306a36Sopenharmony_ciextern const struct inode_operations ntfs_special_inode_operations;
73462306a36Sopenharmony_ciextern const struct dentry_operations ntfs_dentry_ops;
73562306a36Sopenharmony_ci
73662306a36Sopenharmony_ci/* Globals from record.c */
73762306a36Sopenharmony_ciint mi_get(struct ntfs_sb_info *sbi, CLST rno, struct mft_inode **mi);
73862306a36Sopenharmony_civoid mi_put(struct mft_inode *mi);
73962306a36Sopenharmony_ciint mi_init(struct mft_inode *mi, struct ntfs_sb_info *sbi, CLST rno);
74062306a36Sopenharmony_ciint mi_read(struct mft_inode *mi, bool is_mft);
74162306a36Sopenharmony_cistruct ATTRIB *mi_enum_attr(struct mft_inode *mi, struct ATTRIB *attr);
74262306a36Sopenharmony_ci// TODO: id?
74362306a36Sopenharmony_cistruct ATTRIB *mi_find_attr(struct mft_inode *mi, struct ATTRIB *attr,
74462306a36Sopenharmony_ci			    enum ATTR_TYPE type, const __le16 *name,
74562306a36Sopenharmony_ci			    u8 name_len, const __le16 *id);
74662306a36Sopenharmony_cistatic inline struct ATTRIB *rec_find_attr_le(struct mft_inode *rec,
74762306a36Sopenharmony_ci					      struct ATTR_LIST_ENTRY *le)
74862306a36Sopenharmony_ci{
74962306a36Sopenharmony_ci	return mi_find_attr(rec, NULL, le->type, le_name(le), le->name_len,
75062306a36Sopenharmony_ci			    &le->id);
75162306a36Sopenharmony_ci}
75262306a36Sopenharmony_ciint mi_write(struct mft_inode *mi, int wait);
75362306a36Sopenharmony_ciint mi_format_new(struct mft_inode *mi, struct ntfs_sb_info *sbi, CLST rno,
75462306a36Sopenharmony_ci		  __le16 flags, bool is_mft);
75562306a36Sopenharmony_cistruct ATTRIB *mi_insert_attr(struct mft_inode *mi, enum ATTR_TYPE type,
75662306a36Sopenharmony_ci			      const __le16 *name, u8 name_len, u32 asize,
75762306a36Sopenharmony_ci			      u16 name_off);
75862306a36Sopenharmony_ci
75962306a36Sopenharmony_cibool mi_remove_attr(struct ntfs_inode *ni, struct mft_inode *mi,
76062306a36Sopenharmony_ci		    struct ATTRIB *attr);
76162306a36Sopenharmony_cibool mi_resize_attr(struct mft_inode *mi, struct ATTRIB *attr, int bytes);
76262306a36Sopenharmony_ciint mi_pack_runs(struct mft_inode *mi, struct ATTRIB *attr,
76362306a36Sopenharmony_ci		 struct runs_tree *run, CLST len);
76462306a36Sopenharmony_cistatic inline bool mi_is_ref(const struct mft_inode *mi,
76562306a36Sopenharmony_ci			     const struct MFT_REF *ref)
76662306a36Sopenharmony_ci{
76762306a36Sopenharmony_ci	if (le32_to_cpu(ref->low) != mi->rno)
76862306a36Sopenharmony_ci		return false;
76962306a36Sopenharmony_ci	if (ref->seq != mi->mrec->seq)
77062306a36Sopenharmony_ci		return false;
77162306a36Sopenharmony_ci
77262306a36Sopenharmony_ci#ifdef CONFIG_NTFS3_64BIT_CLUSTER
77362306a36Sopenharmony_ci	return le16_to_cpu(ref->high) == (mi->rno >> 32);
77462306a36Sopenharmony_ci#else
77562306a36Sopenharmony_ci	return !ref->high;
77662306a36Sopenharmony_ci#endif
77762306a36Sopenharmony_ci}
77862306a36Sopenharmony_ci
77962306a36Sopenharmony_cistatic inline void mi_get_ref(const struct mft_inode *mi, struct MFT_REF *ref)
78062306a36Sopenharmony_ci{
78162306a36Sopenharmony_ci	ref->low = cpu_to_le32(mi->rno);
78262306a36Sopenharmony_ci#ifdef CONFIG_NTFS3_64BIT_CLUSTER
78362306a36Sopenharmony_ci	ref->high = cpu_to_le16(mi->rno >> 32);
78462306a36Sopenharmony_ci#else
78562306a36Sopenharmony_ci	ref->high = 0;
78662306a36Sopenharmony_ci#endif
78762306a36Sopenharmony_ci	ref->seq = mi->mrec->seq;
78862306a36Sopenharmony_ci}
78962306a36Sopenharmony_ci
79062306a36Sopenharmony_ci/* Globals from run.c */
79162306a36Sopenharmony_cibool run_lookup_entry(const struct runs_tree *run, CLST vcn, CLST *lcn,
79262306a36Sopenharmony_ci		      CLST *len, size_t *index);
79362306a36Sopenharmony_civoid run_truncate(struct runs_tree *run, CLST vcn);
79462306a36Sopenharmony_civoid run_truncate_head(struct runs_tree *run, CLST vcn);
79562306a36Sopenharmony_civoid run_truncate_around(struct runs_tree *run, CLST vcn);
79662306a36Sopenharmony_cibool run_add_entry(struct runs_tree *run, CLST vcn, CLST lcn, CLST len,
79762306a36Sopenharmony_ci		   bool is_mft);
79862306a36Sopenharmony_cibool run_collapse_range(struct runs_tree *run, CLST vcn, CLST len);
79962306a36Sopenharmony_cibool run_insert_range(struct runs_tree *run, CLST vcn, CLST len);
80062306a36Sopenharmony_cibool run_get_entry(const struct runs_tree *run, size_t index, CLST *vcn,
80162306a36Sopenharmony_ci		   CLST *lcn, CLST *len);
80262306a36Sopenharmony_cibool run_is_mapped_full(const struct runs_tree *run, CLST svcn, CLST evcn);
80362306a36Sopenharmony_ci
80462306a36Sopenharmony_ciint run_pack(const struct runs_tree *run, CLST svcn, CLST len, u8 *run_buf,
80562306a36Sopenharmony_ci	     u32 run_buf_size, CLST *packed_vcns);
80662306a36Sopenharmony_ciint run_unpack(struct runs_tree *run, struct ntfs_sb_info *sbi, CLST ino,
80762306a36Sopenharmony_ci	       CLST svcn, CLST evcn, CLST vcn, const u8 *run_buf,
80862306a36Sopenharmony_ci	       int run_buf_size);
80962306a36Sopenharmony_ci
81062306a36Sopenharmony_ci#ifdef NTFS3_CHECK_FREE_CLST
81162306a36Sopenharmony_ciint run_unpack_ex(struct runs_tree *run, struct ntfs_sb_info *sbi, CLST ino,
81262306a36Sopenharmony_ci		  CLST svcn, CLST evcn, CLST vcn, const u8 *run_buf,
81362306a36Sopenharmony_ci		  int run_buf_size);
81462306a36Sopenharmony_ci#else
81562306a36Sopenharmony_ci#define run_unpack_ex run_unpack
81662306a36Sopenharmony_ci#endif
81762306a36Sopenharmony_ciint run_get_highest_vcn(CLST vcn, const u8 *run_buf, u64 *highest_vcn);
81862306a36Sopenharmony_ciint run_clone(const struct runs_tree *run, struct runs_tree *new_run);
81962306a36Sopenharmony_ci
82062306a36Sopenharmony_ci/* Globals from super.c */
82162306a36Sopenharmony_civoid *ntfs_set_shared(void *ptr, u32 bytes);
82262306a36Sopenharmony_civoid *ntfs_put_shared(void *ptr);
82362306a36Sopenharmony_civoid ntfs_unmap_meta(struct super_block *sb, CLST lcn, CLST len);
82462306a36Sopenharmony_ciint ntfs_discard(struct ntfs_sb_info *sbi, CLST Lcn, CLST Len);
82562306a36Sopenharmony_ci
82662306a36Sopenharmony_ci/* Globals from bitmap.c*/
82762306a36Sopenharmony_ciint __init ntfs3_init_bitmap(void);
82862306a36Sopenharmony_civoid ntfs3_exit_bitmap(void);
82962306a36Sopenharmony_civoid wnd_close(struct wnd_bitmap *wnd);
83062306a36Sopenharmony_cistatic inline size_t wnd_zeroes(const struct wnd_bitmap *wnd)
83162306a36Sopenharmony_ci{
83262306a36Sopenharmony_ci	return wnd->total_zeroes;
83362306a36Sopenharmony_ci}
83462306a36Sopenharmony_ciint wnd_init(struct wnd_bitmap *wnd, struct super_block *sb, size_t nbits);
83562306a36Sopenharmony_ciint wnd_set_free(struct wnd_bitmap *wnd, size_t bit, size_t bits);
83662306a36Sopenharmony_ciint wnd_set_used(struct wnd_bitmap *wnd, size_t bit, size_t bits);
83762306a36Sopenharmony_ciint wnd_set_used_safe(struct wnd_bitmap *wnd, size_t bit, size_t bits,
83862306a36Sopenharmony_ci		      size_t *done);
83962306a36Sopenharmony_cibool wnd_is_free(struct wnd_bitmap *wnd, size_t bit, size_t bits);
84062306a36Sopenharmony_cibool wnd_is_used(struct wnd_bitmap *wnd, size_t bit, size_t bits);
84162306a36Sopenharmony_ci
84262306a36Sopenharmony_ci/* Possible values for 'flags' 'wnd_find'. */
84362306a36Sopenharmony_ci#define BITMAP_FIND_MARK_AS_USED 0x01
84462306a36Sopenharmony_ci#define BITMAP_FIND_FULL 0x02
84562306a36Sopenharmony_cisize_t wnd_find(struct wnd_bitmap *wnd, size_t to_alloc, size_t hint,
84662306a36Sopenharmony_ci		size_t flags, size_t *allocated);
84762306a36Sopenharmony_ciint wnd_extend(struct wnd_bitmap *wnd, size_t new_bits);
84862306a36Sopenharmony_civoid wnd_zone_set(struct wnd_bitmap *wnd, size_t Lcn, size_t Len);
84962306a36Sopenharmony_ciint ntfs_trim_fs(struct ntfs_sb_info *sbi, struct fstrim_range *range);
85062306a36Sopenharmony_ci
85162306a36Sopenharmony_civoid ntfs_bitmap_set_le(void *map, unsigned int start, int len);
85262306a36Sopenharmony_civoid ntfs_bitmap_clear_le(void *map, unsigned int start, int len);
85362306a36Sopenharmony_ciunsigned int ntfs_bitmap_weight_le(const void *bitmap, int bits);
85462306a36Sopenharmony_ci
85562306a36Sopenharmony_ci/* Globals from upcase.c */
85662306a36Sopenharmony_ciint ntfs_cmp_names(const __le16 *s1, size_t l1, const __le16 *s2, size_t l2,
85762306a36Sopenharmony_ci		   const u16 *upcase, bool bothcase);
85862306a36Sopenharmony_ciint ntfs_cmp_names_cpu(const struct cpu_str *uni1, const struct le_str *uni2,
85962306a36Sopenharmony_ci		       const u16 *upcase, bool bothcase);
86062306a36Sopenharmony_ciunsigned long ntfs_names_hash(const u16 *name, size_t len, const u16 *upcase,
86162306a36Sopenharmony_ci			      unsigned long hash);
86262306a36Sopenharmony_ci
86362306a36Sopenharmony_ci/* globals from xattr.c */
86462306a36Sopenharmony_ci#ifdef CONFIG_NTFS3_FS_POSIX_ACL
86562306a36Sopenharmony_cistruct posix_acl *ntfs_get_acl(struct mnt_idmap *idmap, struct dentry *dentry,
86662306a36Sopenharmony_ci			       int type);
86762306a36Sopenharmony_ciint ntfs_set_acl(struct mnt_idmap *idmap, struct dentry *dentry,
86862306a36Sopenharmony_ci		 struct posix_acl *acl, int type);
86962306a36Sopenharmony_ciint ntfs_init_acl(struct mnt_idmap *idmap, struct inode *inode,
87062306a36Sopenharmony_ci		  struct inode *dir);
87162306a36Sopenharmony_ci#else
87262306a36Sopenharmony_ci#define ntfs_get_acl NULL
87362306a36Sopenharmony_ci#define ntfs_set_acl NULL
87462306a36Sopenharmony_ci#endif
87562306a36Sopenharmony_ci
87662306a36Sopenharmony_ciint ntfs_acl_chmod(struct mnt_idmap *idmap, struct dentry *dentry);
87762306a36Sopenharmony_cissize_t ntfs_listxattr(struct dentry *dentry, char *buffer, size_t size);
87862306a36Sopenharmony_ciextern const struct xattr_handler *ntfs_xattr_handlers[];
87962306a36Sopenharmony_ci
88062306a36Sopenharmony_ciint ntfs_save_wsl_perm(struct inode *inode, __le16 *ea_size);
88162306a36Sopenharmony_civoid ntfs_get_wsl_perm(struct inode *inode);
88262306a36Sopenharmony_ci
88362306a36Sopenharmony_ci/* globals from lznt.c */
88462306a36Sopenharmony_cistruct lznt *get_lznt_ctx(int level);
88562306a36Sopenharmony_cisize_t compress_lznt(const void *uncompressed, size_t uncompressed_size,
88662306a36Sopenharmony_ci		     void *compressed, size_t compressed_size,
88762306a36Sopenharmony_ci		     struct lznt *ctx);
88862306a36Sopenharmony_cissize_t decompress_lznt(const void *compressed, size_t compressed_size,
88962306a36Sopenharmony_ci			void *uncompressed, size_t uncompressed_size);
89062306a36Sopenharmony_ci
89162306a36Sopenharmony_cistatic inline bool is_ntfs3(struct ntfs_sb_info *sbi)
89262306a36Sopenharmony_ci{
89362306a36Sopenharmony_ci	return sbi->volume.major_ver >= 3;
89462306a36Sopenharmony_ci}
89562306a36Sopenharmony_ci
89662306a36Sopenharmony_ci/* (sb->s_flags & SB_ACTIVE) */
89762306a36Sopenharmony_cistatic inline bool is_mounted(struct ntfs_sb_info *sbi)
89862306a36Sopenharmony_ci{
89962306a36Sopenharmony_ci	return !!sbi->sb->s_root;
90062306a36Sopenharmony_ci}
90162306a36Sopenharmony_ci
90262306a36Sopenharmony_cistatic inline bool ntfs_is_meta_file(struct ntfs_sb_info *sbi, CLST rno)
90362306a36Sopenharmony_ci{
90462306a36Sopenharmony_ci	return rno < MFT_REC_FREE || rno == sbi->objid_no ||
90562306a36Sopenharmony_ci	       rno == sbi->quota_no || rno == sbi->reparse_no ||
90662306a36Sopenharmony_ci	       rno == sbi->usn_jrnl_no;
90762306a36Sopenharmony_ci}
90862306a36Sopenharmony_ci
90962306a36Sopenharmony_cistatic inline void ntfs_unmap_page(struct page *page)
91062306a36Sopenharmony_ci{
91162306a36Sopenharmony_ci	kunmap(page);
91262306a36Sopenharmony_ci	put_page(page);
91362306a36Sopenharmony_ci}
91462306a36Sopenharmony_ci
91562306a36Sopenharmony_cistatic inline struct page *ntfs_map_page(struct address_space *mapping,
91662306a36Sopenharmony_ci					 unsigned long index)
91762306a36Sopenharmony_ci{
91862306a36Sopenharmony_ci	struct page *page = read_mapping_page(mapping, index, NULL);
91962306a36Sopenharmony_ci
92062306a36Sopenharmony_ci	if (!IS_ERR(page))
92162306a36Sopenharmony_ci		kmap(page);
92262306a36Sopenharmony_ci	return page;
92362306a36Sopenharmony_ci}
92462306a36Sopenharmony_ci
92562306a36Sopenharmony_cistatic inline size_t wnd_zone_bit(const struct wnd_bitmap *wnd)
92662306a36Sopenharmony_ci{
92762306a36Sopenharmony_ci	return wnd->zone_bit;
92862306a36Sopenharmony_ci}
92962306a36Sopenharmony_ci
93062306a36Sopenharmony_cistatic inline size_t wnd_zone_len(const struct wnd_bitmap *wnd)
93162306a36Sopenharmony_ci{
93262306a36Sopenharmony_ci	return wnd->zone_end - wnd->zone_bit;
93362306a36Sopenharmony_ci}
93462306a36Sopenharmony_ci
93562306a36Sopenharmony_cistatic inline void run_init(struct runs_tree *run)
93662306a36Sopenharmony_ci{
93762306a36Sopenharmony_ci	run->runs = NULL;
93862306a36Sopenharmony_ci	run->count = 0;
93962306a36Sopenharmony_ci	run->allocated = 0;
94062306a36Sopenharmony_ci}
94162306a36Sopenharmony_ci
94262306a36Sopenharmony_cistatic inline struct runs_tree *run_alloc(void)
94362306a36Sopenharmony_ci{
94462306a36Sopenharmony_ci	return kzalloc(sizeof(struct runs_tree), GFP_NOFS);
94562306a36Sopenharmony_ci}
94662306a36Sopenharmony_ci
94762306a36Sopenharmony_cistatic inline void run_close(struct runs_tree *run)
94862306a36Sopenharmony_ci{
94962306a36Sopenharmony_ci	kvfree(run->runs);
95062306a36Sopenharmony_ci	memset(run, 0, sizeof(*run));
95162306a36Sopenharmony_ci}
95262306a36Sopenharmony_ci
95362306a36Sopenharmony_cistatic inline void run_free(struct runs_tree *run)
95462306a36Sopenharmony_ci{
95562306a36Sopenharmony_ci	if (run) {
95662306a36Sopenharmony_ci		kvfree(run->runs);
95762306a36Sopenharmony_ci		kfree(run);
95862306a36Sopenharmony_ci	}
95962306a36Sopenharmony_ci}
96062306a36Sopenharmony_ci
96162306a36Sopenharmony_cistatic inline bool run_is_empty(struct runs_tree *run)
96262306a36Sopenharmony_ci{
96362306a36Sopenharmony_ci	return !run->count;
96462306a36Sopenharmony_ci}
96562306a36Sopenharmony_ci
96662306a36Sopenharmony_ci/* NTFS uses quad aligned bitmaps. */
96762306a36Sopenharmony_cistatic inline size_t bitmap_size(size_t bits)
96862306a36Sopenharmony_ci{
96962306a36Sopenharmony_ci	return ALIGN((bits + 7) >> 3, 8);
97062306a36Sopenharmony_ci}
97162306a36Sopenharmony_ci
97262306a36Sopenharmony_ci#define _100ns2seconds 10000000
97362306a36Sopenharmony_ci#define SecondsToStartOf1970 0x00000002B6109100
97462306a36Sopenharmony_ci
97562306a36Sopenharmony_ci#define NTFS_TIME_GRAN 100
97662306a36Sopenharmony_ci
97762306a36Sopenharmony_ci/*
97862306a36Sopenharmony_ci * kernel2nt - Converts in-memory kernel timestamp into nt time.
97962306a36Sopenharmony_ci */
98062306a36Sopenharmony_cistatic inline __le64 kernel2nt(const struct timespec64 *ts)
98162306a36Sopenharmony_ci{
98262306a36Sopenharmony_ci	// 10^7 units of 100 nanoseconds one second
98362306a36Sopenharmony_ci	return cpu_to_le64(_100ns2seconds *
98462306a36Sopenharmony_ci				   (ts->tv_sec + SecondsToStartOf1970) +
98562306a36Sopenharmony_ci			   ts->tv_nsec / NTFS_TIME_GRAN);
98662306a36Sopenharmony_ci}
98762306a36Sopenharmony_ci
98862306a36Sopenharmony_ci/*
98962306a36Sopenharmony_ci * nt2kernel - Converts on-disk nt time into kernel timestamp.
99062306a36Sopenharmony_ci */
99162306a36Sopenharmony_cistatic inline void nt2kernel(const __le64 tm, struct timespec64 *ts)
99262306a36Sopenharmony_ci{
99362306a36Sopenharmony_ci	u64 t = le64_to_cpu(tm) - _100ns2seconds * SecondsToStartOf1970;
99462306a36Sopenharmony_ci
99562306a36Sopenharmony_ci	// WARNING: do_div changes its first argument(!)
99662306a36Sopenharmony_ci	ts->tv_nsec = do_div(t, _100ns2seconds) * 100;
99762306a36Sopenharmony_ci	ts->tv_sec = t;
99862306a36Sopenharmony_ci}
99962306a36Sopenharmony_ci
100062306a36Sopenharmony_cistatic inline struct ntfs_sb_info *ntfs_sb(struct super_block *sb)
100162306a36Sopenharmony_ci{
100262306a36Sopenharmony_ci	return sb->s_fs_info;
100362306a36Sopenharmony_ci}
100462306a36Sopenharmony_ci
100562306a36Sopenharmony_cistatic inline int ntfs3_forced_shutdown(struct super_block *sb)
100662306a36Sopenharmony_ci{
100762306a36Sopenharmony_ci	return test_bit(NTFS_FLAGS_SHUTDOWN_BIT, &ntfs_sb(sb)->flags);
100862306a36Sopenharmony_ci}
100962306a36Sopenharmony_ci
101062306a36Sopenharmony_ci/*
101162306a36Sopenharmony_ci * ntfs_up_cluster - Align up on cluster boundary.
101262306a36Sopenharmony_ci */
101362306a36Sopenharmony_cistatic inline u64 ntfs_up_cluster(const struct ntfs_sb_info *sbi, u64 size)
101462306a36Sopenharmony_ci{
101562306a36Sopenharmony_ci	return (size + sbi->cluster_mask) & sbi->cluster_mask_inv;
101662306a36Sopenharmony_ci}
101762306a36Sopenharmony_ci
101862306a36Sopenharmony_ci/*
101962306a36Sopenharmony_ci * ntfs_up_block - Align up on cluster boundary.
102062306a36Sopenharmony_ci */
102162306a36Sopenharmony_cistatic inline u64 ntfs_up_block(const struct super_block *sb, u64 size)
102262306a36Sopenharmony_ci{
102362306a36Sopenharmony_ci	return (size + sb->s_blocksize - 1) & ~(u64)(sb->s_blocksize - 1);
102462306a36Sopenharmony_ci}
102562306a36Sopenharmony_ci
102662306a36Sopenharmony_cistatic inline CLST bytes_to_cluster(const struct ntfs_sb_info *sbi, u64 size)
102762306a36Sopenharmony_ci{
102862306a36Sopenharmony_ci	return (size + sbi->cluster_mask) >> sbi->cluster_bits;
102962306a36Sopenharmony_ci}
103062306a36Sopenharmony_ci
103162306a36Sopenharmony_cistatic inline u64 bytes_to_block(const struct super_block *sb, u64 size)
103262306a36Sopenharmony_ci{
103362306a36Sopenharmony_ci	return (size + sb->s_blocksize - 1) >> sb->s_blocksize_bits;
103462306a36Sopenharmony_ci}
103562306a36Sopenharmony_ci
103662306a36Sopenharmony_cistatic inline struct ntfs_inode *ntfs_i(struct inode *inode)
103762306a36Sopenharmony_ci{
103862306a36Sopenharmony_ci	return container_of(inode, struct ntfs_inode, vfs_inode);
103962306a36Sopenharmony_ci}
104062306a36Sopenharmony_ci
104162306a36Sopenharmony_cistatic inline bool is_compressed(const struct ntfs_inode *ni)
104262306a36Sopenharmony_ci{
104362306a36Sopenharmony_ci	return (ni->std_fa & FILE_ATTRIBUTE_COMPRESSED) ||
104462306a36Sopenharmony_ci	       (ni->ni_flags & NI_FLAG_COMPRESSED_MASK);
104562306a36Sopenharmony_ci}
104662306a36Sopenharmony_ci
104762306a36Sopenharmony_cistatic inline int ni_ext_compress_bits(const struct ntfs_inode *ni)
104862306a36Sopenharmony_ci{
104962306a36Sopenharmony_ci	return 0xb + (ni->ni_flags & NI_FLAG_COMPRESSED_MASK);
105062306a36Sopenharmony_ci}
105162306a36Sopenharmony_ci
105262306a36Sopenharmony_ci/* Bits - 0xc, 0xd, 0xe, 0xf, 0x10 */
105362306a36Sopenharmony_cistatic inline void ni_set_ext_compress_bits(struct ntfs_inode *ni, u8 bits)
105462306a36Sopenharmony_ci{
105562306a36Sopenharmony_ci	ni->ni_flags |= (bits - 0xb) & NI_FLAG_COMPRESSED_MASK;
105662306a36Sopenharmony_ci}
105762306a36Sopenharmony_ci
105862306a36Sopenharmony_cistatic inline bool is_dedup(const struct ntfs_inode *ni)
105962306a36Sopenharmony_ci{
106062306a36Sopenharmony_ci	return ni->ni_flags & NI_FLAG_DEDUPLICATED;
106162306a36Sopenharmony_ci}
106262306a36Sopenharmony_ci
106362306a36Sopenharmony_cistatic inline bool is_encrypted(const struct ntfs_inode *ni)
106462306a36Sopenharmony_ci{
106562306a36Sopenharmony_ci	return ni->std_fa & FILE_ATTRIBUTE_ENCRYPTED;
106662306a36Sopenharmony_ci}
106762306a36Sopenharmony_ci
106862306a36Sopenharmony_cistatic inline bool is_sparsed(const struct ntfs_inode *ni)
106962306a36Sopenharmony_ci{
107062306a36Sopenharmony_ci	return ni->std_fa & FILE_ATTRIBUTE_SPARSE_FILE;
107162306a36Sopenharmony_ci}
107262306a36Sopenharmony_ci
107362306a36Sopenharmony_cistatic inline int is_resident(struct ntfs_inode *ni)
107462306a36Sopenharmony_ci{
107562306a36Sopenharmony_ci	return ni->ni_flags & NI_FLAG_RESIDENT;
107662306a36Sopenharmony_ci}
107762306a36Sopenharmony_ci
107862306a36Sopenharmony_cistatic inline void le16_sub_cpu(__le16 *var, u16 val)
107962306a36Sopenharmony_ci{
108062306a36Sopenharmony_ci	*var = cpu_to_le16(le16_to_cpu(*var) - val);
108162306a36Sopenharmony_ci}
108262306a36Sopenharmony_ci
108362306a36Sopenharmony_cistatic inline void le32_sub_cpu(__le32 *var, u32 val)
108462306a36Sopenharmony_ci{
108562306a36Sopenharmony_ci	*var = cpu_to_le32(le32_to_cpu(*var) - val);
108662306a36Sopenharmony_ci}
108762306a36Sopenharmony_ci
108862306a36Sopenharmony_cistatic inline void nb_put(struct ntfs_buffers *nb)
108962306a36Sopenharmony_ci{
109062306a36Sopenharmony_ci	u32 i, nbufs = nb->nbufs;
109162306a36Sopenharmony_ci
109262306a36Sopenharmony_ci	if (!nbufs)
109362306a36Sopenharmony_ci		return;
109462306a36Sopenharmony_ci
109562306a36Sopenharmony_ci	for (i = 0; i < nbufs; i++)
109662306a36Sopenharmony_ci		put_bh(nb->bh[i]);
109762306a36Sopenharmony_ci	nb->nbufs = 0;
109862306a36Sopenharmony_ci}
109962306a36Sopenharmony_ci
110062306a36Sopenharmony_cistatic inline void put_indx_node(struct indx_node *in)
110162306a36Sopenharmony_ci{
110262306a36Sopenharmony_ci	if (!in)
110362306a36Sopenharmony_ci		return;
110462306a36Sopenharmony_ci
110562306a36Sopenharmony_ci	kfree(in->index);
110662306a36Sopenharmony_ci	nb_put(&in->nb);
110762306a36Sopenharmony_ci	kfree(in);
110862306a36Sopenharmony_ci}
110962306a36Sopenharmony_ci
111062306a36Sopenharmony_cistatic inline void mi_clear(struct mft_inode *mi)
111162306a36Sopenharmony_ci{
111262306a36Sopenharmony_ci	nb_put(&mi->nb);
111362306a36Sopenharmony_ci	kfree(mi->mrec);
111462306a36Sopenharmony_ci	mi->mrec = NULL;
111562306a36Sopenharmony_ci}
111662306a36Sopenharmony_ci
111762306a36Sopenharmony_cistatic inline void ni_lock(struct ntfs_inode *ni)
111862306a36Sopenharmony_ci{
111962306a36Sopenharmony_ci	mutex_lock_nested(&ni->ni_lock, NTFS_INODE_MUTEX_NORMAL);
112062306a36Sopenharmony_ci}
112162306a36Sopenharmony_ci
112262306a36Sopenharmony_cistatic inline void ni_lock_dir(struct ntfs_inode *ni)
112362306a36Sopenharmony_ci{
112462306a36Sopenharmony_ci	mutex_lock_nested(&ni->ni_lock, NTFS_INODE_MUTEX_PARENT);
112562306a36Sopenharmony_ci}
112662306a36Sopenharmony_ci
112762306a36Sopenharmony_cistatic inline void ni_lock_dir2(struct ntfs_inode *ni)
112862306a36Sopenharmony_ci{
112962306a36Sopenharmony_ci	mutex_lock_nested(&ni->ni_lock, NTFS_INODE_MUTEX_PARENT2);
113062306a36Sopenharmony_ci}
113162306a36Sopenharmony_ci
113262306a36Sopenharmony_cistatic inline void ni_unlock(struct ntfs_inode *ni)
113362306a36Sopenharmony_ci{
113462306a36Sopenharmony_ci	mutex_unlock(&ni->ni_lock);
113562306a36Sopenharmony_ci}
113662306a36Sopenharmony_ci
113762306a36Sopenharmony_cistatic inline int ni_trylock(struct ntfs_inode *ni)
113862306a36Sopenharmony_ci{
113962306a36Sopenharmony_ci	return mutex_trylock(&ni->ni_lock);
114062306a36Sopenharmony_ci}
114162306a36Sopenharmony_ci
114262306a36Sopenharmony_cistatic inline int attr_load_runs_attr(struct ntfs_inode *ni,
114362306a36Sopenharmony_ci				      struct ATTRIB *attr,
114462306a36Sopenharmony_ci				      struct runs_tree *run, CLST vcn)
114562306a36Sopenharmony_ci{
114662306a36Sopenharmony_ci	return attr_load_runs_vcn(ni, attr->type, attr_name(attr),
114762306a36Sopenharmony_ci				  attr->name_len, run, vcn);
114862306a36Sopenharmony_ci}
114962306a36Sopenharmony_ci
115062306a36Sopenharmony_cistatic inline void le64_sub_cpu(__le64 *var, u64 val)
115162306a36Sopenharmony_ci{
115262306a36Sopenharmony_ci	*var = cpu_to_le64(le64_to_cpu(*var) - val);
115362306a36Sopenharmony_ci}
115462306a36Sopenharmony_ci
115562306a36Sopenharmony_ci#endif /* _LINUX_NTFS3_NTFS_FS_H */
1156