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 454534a70bSKonstantin Komarov #define NTFS_BLOCKS_PER_MFT_RECORD (MAXIMUM_BYTES_PER_MFT / 512) 464534a70bSKonstantin Komarov 474534a70bSKonstantin Komarov #define MAXIMUM_BYTES_PER_INDEX 4096 484534a70bSKonstantin Komarov #define NTFS_BLOCKS_PER_INODE (MAXIMUM_BYTES_PER_INDEX / 512) 494534a70bSKonstantin Komarov 50e8b8e97fSKari Argillander /* NTFS specific error code when fixup failed. */ 514534a70bSKonstantin Komarov #define E_NTFS_FIXUP 555 52e8b8e97fSKari Argillander /* NTFS specific error code about resident->nonresident. */ 534534a70bSKonstantin Komarov #define E_NTFS_NONRESIDENT 556 54e8b8e97fSKari Argillander /* NTFS specific error code about punch hole. */ 554534a70bSKonstantin Komarov #define E_NTFS_NOTALIGNED 557 564534a70bSKonstantin Komarov 574534a70bSKonstantin Komarov 584534a70bSKonstantin Komarov /* sbi->flags */ 594534a70bSKonstantin Komarov #define NTFS_FLAGS_NODISCARD 0x00000001 60e8b8e97fSKari Argillander /* Set when LogFile is replaying. */ 614534a70bSKonstantin Komarov #define NTFS_FLAGS_LOG_REPLAYING 0x00000008 62e8b8e97fSKari Argillander /* Set when we changed first MFT's which copy must be updated in $MftMirr. */ 634534a70bSKonstantin Komarov #define NTFS_FLAGS_MFTMIRR 0x00001000 644534a70bSKonstantin Komarov #define NTFS_FLAGS_NEED_REPLAY 0x04000000 654534a70bSKonstantin Komarov 664534a70bSKonstantin Komarov 674534a70bSKonstantin Komarov /* ni->ni_flags */ 684534a70bSKonstantin Komarov /* 69e8b8e97fSKari Argillander * Data attribute is external compressed (LZX/Xpress) 704534a70bSKonstantin Komarov * 1 - WOF_COMPRESSION_XPRESS4K 714534a70bSKonstantin Komarov * 2 - WOF_COMPRESSION_XPRESS8K 724534a70bSKonstantin Komarov * 3 - WOF_COMPRESSION_XPRESS16K 734534a70bSKonstantin Komarov * 4 - WOF_COMPRESSION_LZX32K 744534a70bSKonstantin Komarov */ 754534a70bSKonstantin Komarov #define NI_FLAG_COMPRESSED_MASK 0x0000000f 76e8b8e97fSKari Argillander /* Data attribute is deduplicated. */ 774534a70bSKonstantin Komarov #define NI_FLAG_DEDUPLICATED 0x00000010 784534a70bSKonstantin Komarov #define NI_FLAG_EA 0x00000020 794534a70bSKonstantin Komarov #define NI_FLAG_DIR 0x00000040 804534a70bSKonstantin Komarov #define NI_FLAG_RESIDENT 0x00000080 814534a70bSKonstantin Komarov #define NI_FLAG_UPDATE_PARENT 0x00000100 824534a70bSKonstantin Komarov // clang-format on 834534a70bSKonstantin Komarov 844534a70bSKonstantin Komarov struct ntfs_mount_options { 85610f8f5aSKari Argillander char *nls_name; 864534a70bSKonstantin Komarov struct nls_table *nls; 874534a70bSKonstantin Komarov 884534a70bSKonstantin Komarov kuid_t fs_uid; 894534a70bSKonstantin Komarov kgid_t fs_gid; 904534a70bSKonstantin Komarov u16 fs_fmask_inv; 914534a70bSKonstantin Komarov u16 fs_dmask_inv; 924534a70bSKonstantin Komarov 9315b2ae77SKari Argillander unsigned fmask : 1; /* fmask was set. */ 9415b2ae77SKari Argillander unsigned dmask : 1; /*dmask was set. */ 9515b2ae77SKari Argillander unsigned sys_immutable : 1; /* Immutable system files. */ 9615b2ae77SKari Argillander unsigned discard : 1; /* Issue discard requests on deletions. */ 9715b2ae77SKari Argillander unsigned sparse : 1; /* Create sparse files. */ 9815b2ae77SKari Argillander unsigned showmeta : 1; /* Show meta files. */ 9915b2ae77SKari Argillander unsigned nohidden : 1; /* Do not show hidden files. */ 100098250dbSKonstantin Komarov unsigned hide_dot_files : 1; /* Set hidden flag on dot files. */ 1011d07a9dfSDaniel Pinto unsigned windows_names : 1; /* Disallow names forbidden by Windows. */ 10215b2ae77SKari Argillander unsigned force : 1; /* RW mount dirty volume. */ 10315b2ae77SKari Argillander unsigned noacsrules : 1; /* Exclude acs rules. */ 10415b2ae77SKari Argillander unsigned prealloc : 1; /* Preallocate space when file is growing. */ 105a3a956c7SKonstantin Komarov unsigned nocase : 1; /* case insensitive. */ 1064534a70bSKonstantin Komarov }; 1074534a70bSKonstantin Komarov 108e8b8e97fSKari Argillander /* Special value to unpack and deallocate. */ 1094534a70bSKonstantin Komarov #define RUN_DEALLOCATE ((struct runs_tree *)(size_t)1) 1104534a70bSKonstantin Komarov 111e8b8e97fSKari Argillander /* TODO: Use rb tree instead of array. */ 1124534a70bSKonstantin Komarov struct runs_tree { 1134534a70bSKonstantin Komarov struct ntfs_run *runs; 114e8b8e97fSKari Argillander size_t count; /* Currently used size a ntfs_run storage. */ 115e8b8e97fSKari Argillander size_t allocated; /* Currently allocated ntfs_run storage size. */ 1164534a70bSKonstantin Komarov }; 1174534a70bSKonstantin Komarov 1184534a70bSKonstantin Komarov struct ntfs_buffers { 1194534a70bSKonstantin Komarov /* Biggest MFT / smallest cluster = 4096 / 512 = 8 */ 1204534a70bSKonstantin Komarov /* Biggest index / smallest cluster = 4096 / 512 = 8 */ 1214534a70bSKonstantin Komarov struct buffer_head *bh[PAGE_SIZE >> SECTOR_SHIFT]; 1224534a70bSKonstantin Komarov u32 bytes; 1234534a70bSKonstantin Komarov u32 nbufs; 1244534a70bSKonstantin Komarov u32 off; 1254534a70bSKonstantin Komarov }; 1264534a70bSKonstantin Komarov 1274534a70bSKonstantin Komarov enum ALLOCATE_OPT { 128e8b8e97fSKari Argillander ALLOCATE_DEF = 0, // Allocate all clusters. 129e8b8e97fSKari Argillander ALLOCATE_MFT = 1, // Allocate for MFT. 130c380b52fSKonstantin Komarov ALLOCATE_ZERO = 2, // Zeroout new allocated clusters 1314534a70bSKonstantin Komarov }; 1324534a70bSKonstantin Komarov 1334534a70bSKonstantin Komarov enum bitmap_mutex_classes { 1344534a70bSKonstantin Komarov BITMAP_MUTEX_CLUSTERS = 0, 1354534a70bSKonstantin Komarov BITMAP_MUTEX_MFT = 1, 1364534a70bSKonstantin Komarov }; 1374534a70bSKonstantin Komarov 1384534a70bSKonstantin Komarov struct wnd_bitmap { 1394534a70bSKonstantin Komarov struct super_block *sb; 1404534a70bSKonstantin Komarov struct rw_semaphore rw_lock; 1414534a70bSKonstantin Komarov 1424534a70bSKonstantin Komarov struct runs_tree run; 1434534a70bSKonstantin Komarov size_t nbits; 1444534a70bSKonstantin Komarov 145e8b8e97fSKari Argillander size_t total_zeroes; // Total number of free bits. 146e8b8e97fSKari Argillander u16 *free_bits; // Free bits in each window. 1474534a70bSKonstantin Komarov size_t nwnd; 148e8b8e97fSKari Argillander u32 bits_last; // Bits in last window. 1494534a70bSKonstantin Komarov 150e8b8e97fSKari Argillander struct rb_root start_tree; // Extents, sorted by 'start'. 151e8b8e97fSKari Argillander struct rb_root count_tree; // Extents, sorted by 'count + start'. 152e8b8e97fSKari Argillander size_t count; // Extents count. 1534534a70bSKonstantin Komarov 1544534a70bSKonstantin Komarov /* 155e8b8e97fSKari Argillander * -1 Tree is activated but not updated (too many fragments). 156e8b8e97fSKari Argillander * 0 - Tree is not activated. 157e8b8e97fSKari Argillander * 1 - Tree is activated and updated. 1584534a70bSKonstantin Komarov */ 1594534a70bSKonstantin Komarov int uptodated; 160e8b8e97fSKari Argillander size_t extent_min; // Minimal extent used while building. 161e8b8e97fSKari Argillander size_t extent_max; // Upper estimate of biggest free block. 1624534a70bSKonstantin Komarov 1634534a70bSKonstantin Komarov /* Zone [bit, end) */ 1644534a70bSKonstantin Komarov size_t zone_bit; 1654534a70bSKonstantin Komarov size_t zone_end; 1664534a70bSKonstantin Komarov 167e8b8e97fSKari Argillander bool set_tail; // Not necessary in driver. 1684534a70bSKonstantin Komarov bool inited; 1694534a70bSKonstantin Komarov }; 1704534a70bSKonstantin Komarov 1714534a70bSKonstantin Komarov typedef int (*NTFS_CMP_FUNC)(const void *key1, size_t len1, const void *key2, 1724534a70bSKonstantin Komarov size_t len2, const void *param); 1734534a70bSKonstantin Komarov 1744534a70bSKonstantin Komarov enum index_mutex_classed { 1754534a70bSKonstantin Komarov INDEX_MUTEX_I30 = 0, 1764534a70bSKonstantin Komarov INDEX_MUTEX_SII = 1, 1774534a70bSKonstantin Komarov INDEX_MUTEX_SDH = 2, 1784534a70bSKonstantin Komarov INDEX_MUTEX_SO = 3, 1794534a70bSKonstantin Komarov INDEX_MUTEX_SQ = 4, 1804534a70bSKonstantin Komarov INDEX_MUTEX_SR = 5, 1814534a70bSKonstantin Komarov INDEX_MUTEX_TOTAL 1824534a70bSKonstantin Komarov }; 1834534a70bSKonstantin Komarov 184e8b8e97fSKari Argillander /* ntfs_index - Allocation unit inside directory. */ 1854534a70bSKonstantin Komarov struct ntfs_index { 1864534a70bSKonstantin Komarov struct runs_tree bitmap_run; 1874534a70bSKonstantin Komarov struct runs_tree alloc_run; 1884534a70bSKonstantin Komarov /* read/write access to 'bitmap_run'/'alloc_run' while ntfs_readdir */ 1894534a70bSKonstantin Komarov struct rw_semaphore run_lock; 1904534a70bSKonstantin Komarov 191e8b8e97fSKari Argillander /*TODO: Remove 'cmp'. */ 1924534a70bSKonstantin Komarov NTFS_CMP_FUNC cmp; 1934534a70bSKonstantin Komarov 1944534a70bSKonstantin Komarov u8 index_bits; // log2(root->index_block_size) 1954534a70bSKonstantin Komarov u8 idx2vbn_bits; // log2(root->index_block_clst) 1964534a70bSKonstantin Komarov u8 vbn2vbo_bits; // index_block_size < cluster? 9 : cluster_bits 1974534a70bSKonstantin Komarov u8 type; // index_mutex_classed 1984534a70bSKonstantin Komarov }; 1994534a70bSKonstantin Komarov 200e8b8e97fSKari Argillander /* Minimum MFT zone. */ 2014534a70bSKonstantin Komarov #define NTFS_MIN_MFT_ZONE 100 2024534a70bSKonstantin Komarov 203e8b8e97fSKari Argillander /* Ntfs file system in-core superblock data. */ 2044534a70bSKonstantin Komarov struct ntfs_sb_info { 2054534a70bSKonstantin Komarov struct super_block *sb; 2064534a70bSKonstantin Komarov 2074534a70bSKonstantin Komarov u32 discard_granularity; 2084534a70bSKonstantin Komarov u64 discard_granularity_mask_inv; // ~(discard_granularity_mask_inv-1) 2094534a70bSKonstantin Komarov 2104534a70bSKonstantin Komarov u32 cluster_size; // bytes per cluster 2114534a70bSKonstantin Komarov u32 cluster_mask; // == cluster_size - 1 2124534a70bSKonstantin Komarov u64 cluster_mask_inv; // ~(cluster_size - 1) 2134534a70bSKonstantin Komarov u32 block_mask; // sb->s_blocksize - 1 2144534a70bSKonstantin Komarov u32 blocks_per_cluster; // cluster_size / sb->s_blocksize 2154534a70bSKonstantin Komarov 2164534a70bSKonstantin Komarov u32 record_size; 2174534a70bSKonstantin Komarov u32 index_size; 2184534a70bSKonstantin Komarov 2194534a70bSKonstantin Komarov u8 cluster_bits; 2204534a70bSKonstantin Komarov u8 record_bits; 2214534a70bSKonstantin Komarov 222e8b8e97fSKari Argillander u64 maxbytes; // Maximum size for normal files. 223e8b8e97fSKari Argillander u64 maxbytes_sparse; // Maximum size for sparse file. 2244534a70bSKonstantin Komarov 225e8b8e97fSKari Argillander u32 flags; // See NTFS_FLAGS_XXX. 2264534a70bSKonstantin Komarov 2278335ebe1SKonstantin Komarov CLST zone_max; // Maximum MFT zone length in clusters 228e8b8e97fSKari Argillander CLST bad_clusters; // The count of marked bad clusters. 2294534a70bSKonstantin Komarov 230e8b8e97fSKari Argillander u16 max_bytes_per_attr; // Maximum attribute size in record. 231e8b8e97fSKari Argillander u16 attr_size_tr; // Attribute size threshold (320 bytes). 2324534a70bSKonstantin Komarov 233e8b8e97fSKari Argillander /* Records in $Extend. */ 2344534a70bSKonstantin Komarov CLST objid_no; 2354534a70bSKonstantin Komarov CLST quota_no; 2364534a70bSKonstantin Komarov CLST reparse_no; 2374534a70bSKonstantin Komarov CLST usn_jrnl_no; 2384534a70bSKonstantin Komarov 239e8b8e97fSKari Argillander struct ATTR_DEF_ENTRY *def_table; // Attribute definition table. 2404534a70bSKonstantin Komarov u32 def_entries; 2414534a70bSKonstantin Komarov u32 ea_max_size; 2424534a70bSKonstantin Komarov 2434534a70bSKonstantin Komarov struct MFT_REC *new_rec; 2444534a70bSKonstantin Komarov 2454534a70bSKonstantin Komarov u16 *upcase; 2464534a70bSKonstantin Komarov 2474534a70bSKonstantin Komarov struct { 2484534a70bSKonstantin Komarov u64 lbo, lbo2; 2494534a70bSKonstantin Komarov struct ntfs_inode *ni; 2504534a70bSKonstantin Komarov struct wnd_bitmap bitmap; // $MFT::Bitmap 2514534a70bSKonstantin Komarov /* 252e8b8e97fSKari Argillander * MFT records [11-24) used to expand MFT itself. 2534534a70bSKonstantin Komarov * They always marked as used in $MFT::Bitmap 254e8b8e97fSKari Argillander * 'reserved_bitmap' contains real bitmap of these records. 2554534a70bSKonstantin Komarov */ 256e8b8e97fSKari Argillander ulong reserved_bitmap; // Bitmap of used records [11 - 24) 2574534a70bSKonstantin Komarov size_t next_free; // The next record to allocate from 258e8b8e97fSKari Argillander size_t used; // MFT valid size in records. 2594534a70bSKonstantin Komarov u32 recs_mirr; // Number of records in MFTMirr 2604534a70bSKonstantin Komarov u8 next_reserved; 2614534a70bSKonstantin Komarov u8 reserved_bitmap_inited; 2624534a70bSKonstantin Komarov } mft; 2634534a70bSKonstantin Komarov 2644534a70bSKonstantin Komarov struct { 2654534a70bSKonstantin Komarov struct wnd_bitmap bitmap; // $Bitmap::Data 2664534a70bSKonstantin Komarov CLST next_free_lcn; 2674534a70bSKonstantin Komarov } used; 2684534a70bSKonstantin Komarov 2694534a70bSKonstantin Komarov struct { 270e8b8e97fSKari Argillander u64 size; // In bytes. 271e8b8e97fSKari Argillander u64 blocks; // In blocks. 2724534a70bSKonstantin Komarov u64 ser_num; 2734534a70bSKonstantin Komarov struct ntfs_inode *ni; 274e8b8e97fSKari Argillander __le16 flags; // Cached current VOLUME_INFO::flags, VOLUME_FLAG_DIRTY. 2754534a70bSKonstantin Komarov u8 major_ver; 2764534a70bSKonstantin Komarov u8 minor_ver; 2774534a70bSKonstantin Komarov char label[65]; 278e8b8e97fSKari Argillander bool real_dirty; // Real fs state. 2794534a70bSKonstantin Komarov } volume; 2804534a70bSKonstantin Komarov 2814534a70bSKonstantin Komarov struct { 2824534a70bSKonstantin Komarov struct ntfs_index index_sii; 2834534a70bSKonstantin Komarov struct ntfs_index index_sdh; 2844534a70bSKonstantin Komarov struct ntfs_inode *ni; 2854534a70bSKonstantin Komarov u32 next_id; 2864534a70bSKonstantin Komarov u64 next_off; 2874534a70bSKonstantin Komarov 2884534a70bSKonstantin Komarov __le32 def_security_id; 2894534a70bSKonstantin Komarov } security; 2904534a70bSKonstantin Komarov 2914534a70bSKonstantin Komarov struct { 2924534a70bSKonstantin Komarov struct ntfs_index index_r; 2934534a70bSKonstantin Komarov struct ntfs_inode *ni; 2944534a70bSKonstantin Komarov u64 max_size; // 16K 2954534a70bSKonstantin Komarov } reparse; 2964534a70bSKonstantin Komarov 2974534a70bSKonstantin Komarov struct { 2984534a70bSKonstantin Komarov struct ntfs_index index_o; 2994534a70bSKonstantin Komarov struct ntfs_inode *ni; 3004534a70bSKonstantin Komarov } objid; 3014534a70bSKonstantin Komarov 3024534a70bSKonstantin Komarov struct { 3034534a70bSKonstantin Komarov struct mutex mtx_lznt; 3044534a70bSKonstantin Komarov struct lznt *lznt; 3054534a70bSKonstantin Komarov #ifdef CONFIG_NTFS3_LZX_XPRESS 3064534a70bSKonstantin Komarov struct mutex mtx_xpress; 3074534a70bSKonstantin Komarov struct xpress_decompressor *xpress; 3084534a70bSKonstantin Komarov struct mutex mtx_lzx; 3094534a70bSKonstantin Komarov struct lzx_decompressor *lzx; 3104534a70bSKonstantin Komarov #endif 3114534a70bSKonstantin Komarov } compress; 3124534a70bSKonstantin Komarov 313564c97bdSKari Argillander struct ntfs_mount_options *options; 3144534a70bSKonstantin Komarov struct ratelimit_state msg_ratelimit; 3154534a70bSKonstantin Komarov }; 3164534a70bSKonstantin Komarov 317e8b8e97fSKari Argillander /* One MFT record(usually 1024 bytes), consists of attributes. */ 3184534a70bSKonstantin Komarov struct mft_inode { 3194534a70bSKonstantin Komarov struct rb_node node; 3204534a70bSKonstantin Komarov struct ntfs_sb_info *sbi; 3214534a70bSKonstantin Komarov 3224534a70bSKonstantin Komarov struct MFT_REC *mrec; 3234534a70bSKonstantin Komarov struct ntfs_buffers nb; 3244534a70bSKonstantin Komarov 3254534a70bSKonstantin Komarov CLST rno; 3264534a70bSKonstantin Komarov bool dirty; 3274534a70bSKonstantin Komarov }; 3284534a70bSKonstantin Komarov 329e8b8e97fSKari Argillander /* Nested class for ntfs_inode::ni_lock. */ 3304534a70bSKonstantin Komarov enum ntfs_inode_mutex_lock_class { 3314534a70bSKonstantin Komarov NTFS_INODE_MUTEX_DIRTY, 3324534a70bSKonstantin Komarov NTFS_INODE_MUTEX_SECURITY, 3334534a70bSKonstantin Komarov NTFS_INODE_MUTEX_OBJID, 3344534a70bSKonstantin Komarov NTFS_INODE_MUTEX_REPARSE, 3354534a70bSKonstantin Komarov NTFS_INODE_MUTEX_NORMAL, 3364534a70bSKonstantin Komarov NTFS_INODE_MUTEX_PARENT, 337*0ad9dfcbSKonstantin Komarov NTFS_INODE_MUTEX_PARENT2, 3384534a70bSKonstantin Komarov }; 3394534a70bSKonstantin Komarov 3404534a70bSKonstantin Komarov /* 341e8b8e97fSKari Argillander * sturct ntfs_inode 342e8b8e97fSKari Argillander * 343e8b8e97fSKari Argillander * Ntfs inode - extends linux inode. consists of one or more MFT inodes. 3444534a70bSKonstantin Komarov */ 3454534a70bSKonstantin Komarov struct ntfs_inode { 3464534a70bSKonstantin Komarov struct mft_inode mi; // base record 3474534a70bSKonstantin Komarov 3484534a70bSKonstantin Komarov /* 349e8b8e97fSKari Argillander * Valid size: [0 - i_valid) - these range in file contains valid data. 350e8b8e97fSKari Argillander * Range [i_valid - inode->i_size) - contains 0. 351e8b8e97fSKari Argillander * Usually i_valid <= inode->i_size. 3524534a70bSKonstantin Komarov */ 3534534a70bSKonstantin Komarov u64 i_valid; 3544534a70bSKonstantin Komarov struct timespec64 i_crtime; 3554534a70bSKonstantin Komarov 3564534a70bSKonstantin Komarov struct mutex ni_lock; 3574534a70bSKonstantin Komarov 358e8b8e97fSKari Argillander /* File attributes from std. */ 3594534a70bSKonstantin Komarov enum FILE_ATTRIBUTE std_fa; 3604534a70bSKonstantin Komarov __le32 std_security_id; 3614534a70bSKonstantin Komarov 3624534a70bSKonstantin Komarov /* 363e8b8e97fSKari Argillander * Tree of mft_inode. 364e8b8e97fSKari Argillander * Not empty when primary MFT record (usually 1024 bytes) can't save all attributes 365e8b8e97fSKari Argillander * e.g. file becomes too fragmented or contains a lot of names. 3664534a70bSKonstantin Komarov */ 3674534a70bSKonstantin Komarov struct rb_root mi_tree; 3684534a70bSKonstantin Komarov 3694534a70bSKonstantin Komarov /* 3704534a70bSKonstantin Komarov * This member is used in ntfs_readdir to ensure that all subrecords are loaded 3714534a70bSKonstantin Komarov */ 3724534a70bSKonstantin Komarov u8 mi_loaded; 3734534a70bSKonstantin Komarov 3744534a70bSKonstantin Komarov union { 3754534a70bSKonstantin Komarov struct ntfs_index dir; 3764534a70bSKonstantin Komarov struct { 3774534a70bSKonstantin Komarov struct rw_semaphore run_lock; 3784534a70bSKonstantin Komarov struct runs_tree run; 3794534a70bSKonstantin Komarov #ifdef CONFIG_NTFS3_LZX_XPRESS 3804534a70bSKonstantin Komarov struct page *offs_page; 3814534a70bSKonstantin Komarov #endif 3824534a70bSKonstantin Komarov } file; 3834534a70bSKonstantin Komarov }; 3844534a70bSKonstantin Komarov 3854534a70bSKonstantin Komarov struct { 3864534a70bSKonstantin Komarov struct runs_tree run; 387e8b8e97fSKari Argillander struct ATTR_LIST_ENTRY *le; // 1K aligned memory. 3884534a70bSKonstantin Komarov size_t size; 3894534a70bSKonstantin Komarov bool dirty; 3904534a70bSKonstantin Komarov } attr_list; 3914534a70bSKonstantin Komarov 3924534a70bSKonstantin Komarov size_t ni_flags; // NI_FLAG_XXX 3934534a70bSKonstantin Komarov 3944534a70bSKonstantin Komarov struct inode vfs_inode; 3954534a70bSKonstantin Komarov }; 3964534a70bSKonstantin Komarov 3974534a70bSKonstantin Komarov struct indx_node { 3984534a70bSKonstantin Komarov struct ntfs_buffers nb; 3994534a70bSKonstantin Komarov struct INDEX_BUFFER *index; 4004534a70bSKonstantin Komarov }; 4014534a70bSKonstantin Komarov 4024534a70bSKonstantin Komarov struct ntfs_fnd { 4034534a70bSKonstantin Komarov int level; 4044534a70bSKonstantin Komarov struct indx_node *nodes[20]; 4054534a70bSKonstantin Komarov struct NTFS_DE *de[20]; 4064534a70bSKonstantin Komarov struct NTFS_DE *root_de; 4074534a70bSKonstantin Komarov }; 4084534a70bSKonstantin Komarov 4094534a70bSKonstantin Komarov enum REPARSE_SIGN { 4104534a70bSKonstantin Komarov REPARSE_NONE = 0, 4114534a70bSKonstantin Komarov REPARSE_COMPRESSED = 1, 4124534a70bSKonstantin Komarov REPARSE_DEDUPLICATED = 2, 4134534a70bSKonstantin Komarov REPARSE_LINK = 3 4144534a70bSKonstantin Komarov }; 4154534a70bSKonstantin Komarov 416e8b8e97fSKari Argillander /* Functions from attrib.c */ 4174534a70bSKonstantin Komarov int attr_allocate_clusters(struct ntfs_sb_info *sbi, struct runs_tree *run, 4184534a70bSKonstantin Komarov CLST vcn, CLST lcn, CLST len, CLST *pre_alloc, 4194534a70bSKonstantin Komarov enum ALLOCATE_OPT opt, CLST *alen, const size_t fr, 420c380b52fSKonstantin Komarov CLST *new_lcn, CLST *new_len); 4214534a70bSKonstantin Komarov int attr_make_nonresident(struct ntfs_inode *ni, struct ATTRIB *attr, 4224534a70bSKonstantin Komarov struct ATTR_LIST_ENTRY *le, struct mft_inode *mi, 4234534a70bSKonstantin Komarov u64 new_size, struct runs_tree *run, 4244534a70bSKonstantin Komarov struct ATTRIB **ins_attr, struct page *page); 4254534a70bSKonstantin Komarov int attr_set_size(struct ntfs_inode *ni, enum ATTR_TYPE type, 4264534a70bSKonstantin Komarov const __le16 *name, u8 name_len, struct runs_tree *run, 4274534a70bSKonstantin Komarov u64 new_size, const u64 *new_valid, bool keep_prealloc, 4284534a70bSKonstantin Komarov struct ATTRIB **ret); 4294534a70bSKonstantin Komarov int attr_data_get_block(struct ntfs_inode *ni, CLST vcn, CLST clen, CLST *lcn, 430c380b52fSKonstantin Komarov CLST *len, bool *new, bool zero); 4314534a70bSKonstantin Komarov int attr_data_read_resident(struct ntfs_inode *ni, struct page *page); 4324534a70bSKonstantin Komarov int attr_data_write_resident(struct ntfs_inode *ni, struct page *page); 4334534a70bSKonstantin Komarov int attr_load_runs_vcn(struct ntfs_inode *ni, enum ATTR_TYPE type, 4344534a70bSKonstantin Komarov const __le16 *name, u8 name_len, struct runs_tree *run, 4354534a70bSKonstantin Komarov CLST vcn); 4364534a70bSKonstantin Komarov int attr_load_runs_range(struct ntfs_inode *ni, enum ATTR_TYPE type, 4374534a70bSKonstantin Komarov const __le16 *name, u8 name_len, struct runs_tree *run, 4384534a70bSKonstantin Komarov u64 from, u64 to); 4394534a70bSKonstantin Komarov int attr_wof_frame_info(struct ntfs_inode *ni, struct ATTRIB *attr, 4404534a70bSKonstantin Komarov struct runs_tree *run, u64 frame, u64 frames, 4414534a70bSKonstantin Komarov u8 frame_bits, u32 *ondisk_size, u64 *vbo_data); 4424534a70bSKonstantin Komarov int attr_is_frame_compressed(struct ntfs_inode *ni, struct ATTRIB *attr, 4434534a70bSKonstantin Komarov CLST frame, CLST *clst_data); 4444534a70bSKonstantin Komarov int attr_allocate_frame(struct ntfs_inode *ni, CLST frame, size_t compr_size, 4454534a70bSKonstantin Komarov u64 new_valid); 4464534a70bSKonstantin Komarov int attr_collapse_range(struct ntfs_inode *ni, u64 vbo, u64 bytes); 447aa30eccbSKonstantin Komarov int attr_insert_range(struct ntfs_inode *ni, u64 vbo, u64 bytes); 4484534a70bSKonstantin Komarov int attr_punch_hole(struct ntfs_inode *ni, u64 vbo, u64 bytes, u32 *frame_size); 4494534a70bSKonstantin Komarov 450e8b8e97fSKari Argillander /* Functions from attrlist.c */ 4514534a70bSKonstantin Komarov void al_destroy(struct ntfs_inode *ni); 4524534a70bSKonstantin Komarov bool al_verify(struct ntfs_inode *ni); 4534534a70bSKonstantin Komarov int ntfs_load_attr_list(struct ntfs_inode *ni, struct ATTRIB *attr); 4544534a70bSKonstantin Komarov struct ATTR_LIST_ENTRY *al_enumerate(struct ntfs_inode *ni, 4554534a70bSKonstantin Komarov struct ATTR_LIST_ENTRY *le); 4564534a70bSKonstantin Komarov struct ATTR_LIST_ENTRY *al_find_le(struct ntfs_inode *ni, 4574534a70bSKonstantin Komarov struct ATTR_LIST_ENTRY *le, 4584534a70bSKonstantin Komarov const struct ATTRIB *attr); 4594534a70bSKonstantin Komarov struct ATTR_LIST_ENTRY *al_find_ex(struct ntfs_inode *ni, 4604534a70bSKonstantin Komarov struct ATTR_LIST_ENTRY *le, 4614534a70bSKonstantin Komarov enum ATTR_TYPE type, const __le16 *name, 4624534a70bSKonstantin Komarov u8 name_len, const CLST *vcn); 4634534a70bSKonstantin Komarov int al_add_le(struct ntfs_inode *ni, enum ATTR_TYPE type, const __le16 *name, 4644534a70bSKonstantin Komarov u8 name_len, CLST svcn, __le16 id, const struct MFT_REF *ref, 4654534a70bSKonstantin Komarov struct ATTR_LIST_ENTRY **new_le); 4664534a70bSKonstantin Komarov bool al_remove_le(struct ntfs_inode *ni, struct ATTR_LIST_ENTRY *le); 4674534a70bSKonstantin Komarov bool al_delete_le(struct ntfs_inode *ni, enum ATTR_TYPE type, CLST vcn, 4684534a70bSKonstantin Komarov const __le16 *name, size_t name_len, 4694534a70bSKonstantin Komarov const struct MFT_REF *ref); 47063544672SKonstantin Komarov int al_update(struct ntfs_inode *ni, int sync); 4714534a70bSKonstantin Komarov static inline size_t al_aligned(size_t size) 4724534a70bSKonstantin Komarov { 4734534a70bSKonstantin Komarov return (size + 1023) & ~(size_t)1023; 4744534a70bSKonstantin Komarov } 4754534a70bSKonstantin Komarov 476e8b8e97fSKari Argillander /* Globals from bitfunc.c */ 47708811ba5SKonstantin Komarov bool are_bits_clear(const void *map, size_t bit, size_t nbits); 47808811ba5SKonstantin Komarov bool are_bits_set(const void *map, size_t bit, size_t nbits); 47908811ba5SKonstantin Komarov size_t get_set_bits_ex(const void *map, size_t bit, size_t nbits); 4804534a70bSKonstantin Komarov 481e8b8e97fSKari Argillander /* Globals from dir.c */ 4822c690788SKonstantin Komarov int ntfs_utf16_to_nls(struct ntfs_sb_info *sbi, const __le16 *name, u32 len, 4834534a70bSKonstantin Komarov u8 *buf, int buf_len); 4844534a70bSKonstantin Komarov int ntfs_nls_to_utf16(struct ntfs_sb_info *sbi, const u8 *name, u32 name_len, 4854534a70bSKonstantin Komarov struct cpu_str *uni, u32 max_ulen, 4864534a70bSKonstantin Komarov enum utf16_endian endian); 4874534a70bSKonstantin Komarov struct inode *dir_search_u(struct inode *dir, const struct cpu_str *uni, 4884534a70bSKonstantin Komarov struct ntfs_fnd *fnd); 4894534a70bSKonstantin Komarov bool dir_is_empty(struct inode *dir); 4904534a70bSKonstantin Komarov extern const struct file_operations ntfs_dir_operations; 4914534a70bSKonstantin Komarov 492e8b8e97fSKari Argillander /* Globals from file.c */ 4934534a70bSKonstantin Komarov int ntfs_getattr(struct user_namespace *mnt_userns, const struct path *path, 4944534a70bSKonstantin Komarov struct kstat *stat, u32 request_mask, u32 flags); 4954534a70bSKonstantin Komarov int ntfs3_setattr(struct user_namespace *mnt_userns, struct dentry *dentry, 4964534a70bSKonstantin Komarov struct iattr *attr); 4974534a70bSKonstantin Komarov int ntfs_file_open(struct inode *inode, struct file *file); 4984534a70bSKonstantin Komarov int ntfs_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, 4994534a70bSKonstantin Komarov __u64 start, __u64 len); 5004534a70bSKonstantin Komarov extern const struct inode_operations ntfs_special_inode_operations; 5014534a70bSKonstantin Komarov extern const struct inode_operations ntfs_file_inode_operations; 5024534a70bSKonstantin Komarov extern const struct file_operations ntfs_file_operations; 5034534a70bSKonstantin Komarov 504e8b8e97fSKari Argillander /* Globals from frecord.c */ 5054534a70bSKonstantin Komarov void ni_remove_mi(struct ntfs_inode *ni, struct mft_inode *mi); 5064534a70bSKonstantin Komarov struct ATTR_STD_INFO *ni_std(struct ntfs_inode *ni); 5074534a70bSKonstantin Komarov struct ATTR_STD_INFO5 *ni_std5(struct ntfs_inode *ni); 5084534a70bSKonstantin Komarov void ni_clear(struct ntfs_inode *ni); 5094534a70bSKonstantin Komarov int ni_load_mi_ex(struct ntfs_inode *ni, CLST rno, struct mft_inode **mi); 51078ab59feSKonstantin Komarov int ni_load_mi(struct ntfs_inode *ni, const struct ATTR_LIST_ENTRY *le, 5114534a70bSKonstantin Komarov struct mft_inode **mi); 5124534a70bSKonstantin Komarov struct ATTRIB *ni_find_attr(struct ntfs_inode *ni, struct ATTRIB *attr, 5134534a70bSKonstantin Komarov struct ATTR_LIST_ENTRY **entry_o, 5144534a70bSKonstantin Komarov enum ATTR_TYPE type, const __le16 *name, 5154534a70bSKonstantin Komarov u8 name_len, const CLST *vcn, 5164534a70bSKonstantin Komarov struct mft_inode **mi); 5174534a70bSKonstantin Komarov struct ATTRIB *ni_enum_attr_ex(struct ntfs_inode *ni, struct ATTRIB *attr, 5184534a70bSKonstantin Komarov struct ATTR_LIST_ENTRY **le, 5194534a70bSKonstantin Komarov struct mft_inode **mi); 5204534a70bSKonstantin Komarov struct ATTRIB *ni_load_attr(struct ntfs_inode *ni, enum ATTR_TYPE type, 5214534a70bSKonstantin Komarov const __le16 *name, u8 name_len, CLST vcn, 5224534a70bSKonstantin Komarov struct mft_inode **pmi); 5234534a70bSKonstantin Komarov int ni_load_all_mi(struct ntfs_inode *ni); 5244534a70bSKonstantin Komarov bool ni_add_subrecord(struct ntfs_inode *ni, CLST rno, struct mft_inode **mi); 5254534a70bSKonstantin Komarov int ni_remove_attr(struct ntfs_inode *ni, enum ATTR_TYPE type, 5264534a70bSKonstantin Komarov const __le16 *name, size_t name_len, bool base_only, 5274534a70bSKonstantin Komarov const __le16 *id); 5284534a70bSKonstantin Komarov int ni_create_attr_list(struct ntfs_inode *ni); 5294534a70bSKonstantin Komarov int ni_expand_list(struct ntfs_inode *ni); 5304534a70bSKonstantin Komarov int ni_insert_nonresident(struct ntfs_inode *ni, enum ATTR_TYPE type, 5314534a70bSKonstantin Komarov const __le16 *name, u8 name_len, 5324534a70bSKonstantin Komarov const struct runs_tree *run, CLST svcn, CLST len, 5334534a70bSKonstantin Komarov __le16 flags, struct ATTRIB **new_attr, 534c1e0ab37SKonstantin Komarov struct mft_inode **mi, struct ATTR_LIST_ENTRY **le); 5354534a70bSKonstantin Komarov int ni_insert_resident(struct ntfs_inode *ni, u32 data_size, 5364534a70bSKonstantin Komarov enum ATTR_TYPE type, const __le16 *name, u8 name_len, 53778ab59feSKonstantin Komarov struct ATTRIB **new_attr, struct mft_inode **mi, 53878ab59feSKonstantin Komarov struct ATTR_LIST_ENTRY **le); 53978ab59feSKonstantin Komarov void ni_remove_attr_le(struct ntfs_inode *ni, struct ATTRIB *attr, 54078ab59feSKonstantin Komarov struct mft_inode *mi, struct ATTR_LIST_ENTRY *le); 5414534a70bSKonstantin Komarov int ni_delete_all(struct ntfs_inode *ni); 5424534a70bSKonstantin Komarov struct ATTR_FILE_NAME *ni_fname_name(struct ntfs_inode *ni, 5434534a70bSKonstantin Komarov const struct cpu_str *uni, 5444534a70bSKonstantin Komarov const struct MFT_REF *home, 54578ab59feSKonstantin Komarov struct mft_inode **mi, 5464534a70bSKonstantin Komarov struct ATTR_LIST_ENTRY **entry); 5474534a70bSKonstantin Komarov struct ATTR_FILE_NAME *ni_fname_type(struct ntfs_inode *ni, u8 name_type, 54878ab59feSKonstantin Komarov struct mft_inode **mi, 5494534a70bSKonstantin Komarov struct ATTR_LIST_ENTRY **entry); 5504534a70bSKonstantin Komarov int ni_new_attr_flags(struct ntfs_inode *ni, enum FILE_ATTRIBUTE new_fa); 5514534a70bSKonstantin Komarov enum REPARSE_SIGN ni_parse_reparse(struct ntfs_inode *ni, struct ATTRIB *attr, 552cd4c76ffSKonstantin Komarov struct REPARSE_DATA_BUFFER *buffer); 5534534a70bSKonstantin Komarov int ni_write_inode(struct inode *inode, int sync, const char *hint); 5544534a70bSKonstantin Komarov #define _ni_write_inode(i, w) ni_write_inode(i, w, __func__) 5554534a70bSKonstantin Komarov int ni_fiemap(struct ntfs_inode *ni, struct fiemap_extent_info *fieinfo, 5564534a70bSKonstantin Komarov __u64 vbo, __u64 len); 5574534a70bSKonstantin Komarov int ni_readpage_cmpr(struct ntfs_inode *ni, struct page *page); 5584534a70bSKonstantin Komarov int ni_decompress_file(struct ntfs_inode *ni); 5594534a70bSKonstantin Komarov int ni_read_frame(struct ntfs_inode *ni, u64 frame_vbo, struct page **pages, 5604534a70bSKonstantin Komarov u32 pages_per_frame); 5614534a70bSKonstantin Komarov int ni_write_frame(struct ntfs_inode *ni, struct page **pages, 5624534a70bSKonstantin Komarov u32 pages_per_frame); 56378ab59feSKonstantin Komarov int ni_remove_name(struct ntfs_inode *dir_ni, struct ntfs_inode *ni, 56478ab59feSKonstantin Komarov struct NTFS_DE *de, struct NTFS_DE **de2, int *undo_step); 56578ab59feSKonstantin Komarov 56678ab59feSKonstantin Komarov bool ni_remove_name_undo(struct ntfs_inode *dir_ni, struct ntfs_inode *ni, 56778ab59feSKonstantin Komarov struct NTFS_DE *de, struct NTFS_DE *de2, 56878ab59feSKonstantin Komarov int undo_step); 56978ab59feSKonstantin Komarov 57078ab59feSKonstantin Komarov int ni_add_name(struct ntfs_inode *dir_ni, struct ntfs_inode *ni, 57178ab59feSKonstantin Komarov struct NTFS_DE *de); 57278ab59feSKonstantin Komarov 57378ab59feSKonstantin Komarov int ni_rename(struct ntfs_inode *dir_ni, struct ntfs_inode *new_dir_ni, 57478ab59feSKonstantin Komarov struct ntfs_inode *ni, struct NTFS_DE *de, struct NTFS_DE *new_de, 57578ab59feSKonstantin Komarov bool *is_bad); 57678ab59feSKonstantin Komarov 57778ab59feSKonstantin Komarov bool ni_is_dirty(struct inode *inode); 5784534a70bSKonstantin Komarov 579e8b8e97fSKari Argillander /* Globals from fslog.c */ 5804534a70bSKonstantin Komarov int log_replay(struct ntfs_inode *ni, bool *initialized); 5814534a70bSKonstantin Komarov 582e8b8e97fSKari Argillander /* Globals from fsntfs.c */ 5834534a70bSKonstantin Komarov bool ntfs_fix_pre_write(struct NTFS_RECORD_HEADER *rhdr, size_t bytes); 5844534a70bSKonstantin Komarov int ntfs_fix_post_read(struct NTFS_RECORD_HEADER *rhdr, size_t bytes, 5854534a70bSKonstantin Komarov bool simple); 5864534a70bSKonstantin Komarov int ntfs_extend_init(struct ntfs_sb_info *sbi); 5874534a70bSKonstantin Komarov int ntfs_loadlog_and_replay(struct ntfs_inode *ni, struct ntfs_sb_info *sbi); 5884534a70bSKonstantin Komarov int ntfs_look_for_free_space(struct ntfs_sb_info *sbi, CLST lcn, CLST len, 5894534a70bSKonstantin Komarov CLST *new_lcn, CLST *new_len, 5904534a70bSKonstantin Komarov enum ALLOCATE_OPT opt); 5914534a70bSKonstantin Komarov int ntfs_look_free_mft(struct ntfs_sb_info *sbi, CLST *rno, bool mft, 5924534a70bSKonstantin Komarov struct ntfs_inode *ni, struct mft_inode **mi); 593071100eaSKonstantin Komarov void ntfs_mark_rec_free(struct ntfs_sb_info *sbi, CLST rno, bool is_mft); 5944534a70bSKonstantin Komarov int ntfs_clear_mft_tail(struct ntfs_sb_info *sbi, size_t from, size_t to); 5954534a70bSKonstantin Komarov int ntfs_refresh_zone(struct ntfs_sb_info *sbi); 596e66af07cSPavel Skripkin void ntfs_update_mftmirr(struct ntfs_sb_info *sbi, int wait); 597c12df45eSKonstantin Komarov void ntfs_bad_inode(struct inode *inode, const char *hint); 598c12df45eSKonstantin Komarov #define _ntfs_bad_inode(i) ntfs_bad_inode(i, __func__) 5994534a70bSKonstantin Komarov enum NTFS_DIRTY_FLAGS { 6004534a70bSKonstantin Komarov NTFS_DIRTY_CLEAR = 0, 6014534a70bSKonstantin Komarov NTFS_DIRTY_DIRTY = 1, 6024534a70bSKonstantin Komarov NTFS_DIRTY_ERROR = 2, 6034534a70bSKonstantin Komarov }; 6044534a70bSKonstantin Komarov int ntfs_set_state(struct ntfs_sb_info *sbi, enum NTFS_DIRTY_FLAGS dirty); 6054534a70bSKonstantin Komarov int ntfs_sb_read(struct super_block *sb, u64 lbo, size_t bytes, void *buffer); 6064534a70bSKonstantin Komarov int ntfs_sb_write(struct super_block *sb, u64 lbo, size_t bytes, 6074534a70bSKonstantin Komarov const void *buffer, int wait); 6084534a70bSKonstantin Komarov int ntfs_sb_write_run(struct ntfs_sb_info *sbi, const struct runs_tree *run, 60963544672SKonstantin Komarov u64 vbo, const void *buf, size_t bytes, int sync); 6104534a70bSKonstantin Komarov struct buffer_head *ntfs_bread_run(struct ntfs_sb_info *sbi, 6114534a70bSKonstantin Komarov const struct runs_tree *run, u64 vbo); 6124534a70bSKonstantin Komarov int ntfs_read_run_nb(struct ntfs_sb_info *sbi, const struct runs_tree *run, 6134534a70bSKonstantin Komarov u64 vbo, void *buf, u32 bytes, struct ntfs_buffers *nb); 6144534a70bSKonstantin Komarov int ntfs_read_bh(struct ntfs_sb_info *sbi, const struct runs_tree *run, u64 vbo, 6154534a70bSKonstantin Komarov struct NTFS_RECORD_HEADER *rhdr, u32 bytes, 6164534a70bSKonstantin Komarov struct ntfs_buffers *nb); 6174534a70bSKonstantin Komarov int ntfs_get_bh(struct ntfs_sb_info *sbi, const struct runs_tree *run, u64 vbo, 6184534a70bSKonstantin Komarov u32 bytes, struct ntfs_buffers *nb); 6194534a70bSKonstantin Komarov int ntfs_write_bh(struct ntfs_sb_info *sbi, struct NTFS_RECORD_HEADER *rhdr, 6204534a70bSKonstantin Komarov struct ntfs_buffers *nb, int sync); 6214534a70bSKonstantin Komarov int ntfs_bio_pages(struct ntfs_sb_info *sbi, const struct runs_tree *run, 6224534a70bSKonstantin Komarov struct page **pages, u32 nr_pages, u64 vbo, u32 bytes, 623ce6b5315SBart Van Assche enum req_op op); 6244534a70bSKonstantin Komarov int ntfs_bio_fill_1(struct ntfs_sb_info *sbi, const struct runs_tree *run); 6254534a70bSKonstantin Komarov int ntfs_vbo_to_lbo(struct ntfs_sb_info *sbi, const struct runs_tree *run, 6264534a70bSKonstantin Komarov u64 vbo, u64 *lbo, u64 *bytes); 6274534a70bSKonstantin Komarov struct ntfs_inode *ntfs_new_inode(struct ntfs_sb_info *sbi, CLST nRec, 6284534a70bSKonstantin Komarov bool dir); 6294534a70bSKonstantin Komarov extern const u8 s_default_security[0x50]; 6304534a70bSKonstantin Komarov bool is_sd_valid(const struct SECURITY_DESCRIPTOR_RELATIVE *sd, u32 len); 6314534a70bSKonstantin Komarov int ntfs_security_init(struct ntfs_sb_info *sbi); 6324534a70bSKonstantin Komarov int ntfs_get_security_by_id(struct ntfs_sb_info *sbi, __le32 security_id, 6334534a70bSKonstantin Komarov struct SECURITY_DESCRIPTOR_RELATIVE **sd, 6344534a70bSKonstantin Komarov size_t *size); 6354534a70bSKonstantin Komarov int ntfs_insert_security(struct ntfs_sb_info *sbi, 6364534a70bSKonstantin Komarov const struct SECURITY_DESCRIPTOR_RELATIVE *sd, 6374534a70bSKonstantin Komarov u32 size, __le32 *security_id, bool *inserted); 6384534a70bSKonstantin Komarov int ntfs_reparse_init(struct ntfs_sb_info *sbi); 6394534a70bSKonstantin Komarov int ntfs_objid_init(struct ntfs_sb_info *sbi); 6404534a70bSKonstantin Komarov int ntfs_objid_remove(struct ntfs_sb_info *sbi, struct GUID *guid); 6414534a70bSKonstantin Komarov int ntfs_insert_reparse(struct ntfs_sb_info *sbi, __le32 rtag, 6424534a70bSKonstantin Komarov const struct MFT_REF *ref); 6434534a70bSKonstantin Komarov int ntfs_remove_reparse(struct ntfs_sb_info *sbi, __le32 rtag, 6444534a70bSKonstantin Komarov const struct MFT_REF *ref); 6454534a70bSKonstantin Komarov void mark_as_free_ex(struct ntfs_sb_info *sbi, CLST lcn, CLST len, bool trim); 6464534a70bSKonstantin Komarov int run_deallocate(struct ntfs_sb_info *sbi, struct runs_tree *run, bool trim); 6471d07a9dfSDaniel Pinto bool valid_windows_name(struct ntfs_sb_info *sbi, const struct le_str *name); 6484534a70bSKonstantin Komarov 649e8b8e97fSKari Argillander /* Globals from index.c */ 6504534a70bSKonstantin Komarov int indx_used_bit(struct ntfs_index *indx, struct ntfs_inode *ni, size_t *bit); 6514534a70bSKonstantin Komarov void fnd_clear(struct ntfs_fnd *fnd); 6524534a70bSKonstantin Komarov static inline struct ntfs_fnd *fnd_get(void) 6534534a70bSKonstantin Komarov { 654195c52bdSKari Argillander return kzalloc(sizeof(struct ntfs_fnd), GFP_NOFS); 6554534a70bSKonstantin Komarov } 6564534a70bSKonstantin Komarov static inline void fnd_put(struct ntfs_fnd *fnd) 6574534a70bSKonstantin Komarov { 6584534a70bSKonstantin Komarov if (fnd) { 6594534a70bSKonstantin Komarov fnd_clear(fnd); 660195c52bdSKari Argillander kfree(fnd); 6614534a70bSKonstantin Komarov } 6624534a70bSKonstantin Komarov } 6634534a70bSKonstantin Komarov void indx_clear(struct ntfs_index *idx); 6644534a70bSKonstantin Komarov int indx_init(struct ntfs_index *indx, struct ntfs_sb_info *sbi, 6654534a70bSKonstantin Komarov const struct ATTRIB *attr, enum index_mutex_classed type); 6664534a70bSKonstantin Komarov struct INDEX_ROOT *indx_get_root(struct ntfs_index *indx, struct ntfs_inode *ni, 6674534a70bSKonstantin Komarov struct ATTRIB **attr, struct mft_inode **mi); 6684534a70bSKonstantin Komarov int indx_read(struct ntfs_index *idx, struct ntfs_inode *ni, CLST vbn, 6694534a70bSKonstantin Komarov struct indx_node **node); 6704534a70bSKonstantin Komarov int indx_find(struct ntfs_index *indx, struct ntfs_inode *dir, 6714534a70bSKonstantin Komarov const struct INDEX_ROOT *root, const void *Key, size_t KeyLen, 6724534a70bSKonstantin Komarov const void *param, int *diff, struct NTFS_DE **entry, 6734534a70bSKonstantin Komarov struct ntfs_fnd *fnd); 6744534a70bSKonstantin Komarov int indx_find_sort(struct ntfs_index *indx, struct ntfs_inode *ni, 6754534a70bSKonstantin Komarov const struct INDEX_ROOT *root, struct NTFS_DE **entry, 6764534a70bSKonstantin Komarov struct ntfs_fnd *fnd); 6774534a70bSKonstantin Komarov int indx_find_raw(struct ntfs_index *indx, struct ntfs_inode *ni, 6784534a70bSKonstantin Komarov const struct INDEX_ROOT *root, struct NTFS_DE **entry, 6794534a70bSKonstantin Komarov size_t *off, struct ntfs_fnd *fnd); 6804534a70bSKonstantin Komarov int indx_insert_entry(struct ntfs_index *indx, struct ntfs_inode *ni, 6814534a70bSKonstantin Komarov const struct NTFS_DE *new_de, const void *param, 68278ab59feSKonstantin Komarov struct ntfs_fnd *fnd, bool undo); 6834534a70bSKonstantin Komarov int indx_delete_entry(struct ntfs_index *indx, struct ntfs_inode *ni, 6844534a70bSKonstantin Komarov const void *key, u32 key_len, const void *param); 6854534a70bSKonstantin Komarov int indx_update_dup(struct ntfs_inode *ni, struct ntfs_sb_info *sbi, 6864534a70bSKonstantin Komarov const struct ATTR_FILE_NAME *fname, 6874534a70bSKonstantin Komarov const struct NTFS_DUP_INFO *dup, int sync); 6884534a70bSKonstantin Komarov 689e8b8e97fSKari Argillander /* Globals from inode.c */ 6904534a70bSKonstantin Komarov struct inode *ntfs_iget5(struct super_block *sb, const struct MFT_REF *ref, 6914534a70bSKonstantin Komarov const struct cpu_str *name); 6924534a70bSKonstantin Komarov int ntfs_set_size(struct inode *inode, u64 new_size); 6934534a70bSKonstantin Komarov int reset_log_file(struct inode *inode); 6944534a70bSKonstantin Komarov int ntfs_get_block(struct inode *inode, sector_t vbn, 6954534a70bSKonstantin Komarov struct buffer_head *bh_result, int create); 69644ab23b9SMatthew Wilcox (Oracle) int ntfs_write_begin(struct file *file, struct address_space *mapping, 69744ab23b9SMatthew Wilcox (Oracle) loff_t pos, u32 len, struct page **pagep, void **fsdata); 69844ab23b9SMatthew Wilcox (Oracle) int ntfs_write_end(struct file *file, struct address_space *mapping, 69944ab23b9SMatthew Wilcox (Oracle) loff_t pos, u32 len, u32 copied, struct page *page, 70044ab23b9SMatthew Wilcox (Oracle) void *fsdata); 7014534a70bSKonstantin Komarov int ntfs3_write_inode(struct inode *inode, struct writeback_control *wbc); 7024534a70bSKonstantin Komarov int ntfs_sync_inode(struct inode *inode); 7034534a70bSKonstantin Komarov int ntfs_flush_inodes(struct super_block *sb, struct inode *i1, 7044534a70bSKonstantin Komarov struct inode *i2); 7054534a70bSKonstantin Komarov int inode_write_data(struct inode *inode, const void *data, size_t bytes); 7064534a70bSKonstantin Komarov struct inode *ntfs_create_inode(struct user_namespace *mnt_userns, 7074534a70bSKonstantin Komarov struct inode *dir, struct dentry *dentry, 7084534a70bSKonstantin Komarov const struct cpu_str *uni, umode_t mode, 7094534a70bSKonstantin Komarov dev_t dev, const char *symname, u32 size, 7104534a70bSKonstantin Komarov struct ntfs_fnd *fnd); 7114534a70bSKonstantin Komarov int ntfs_link_inode(struct inode *inode, struct dentry *dentry); 7124534a70bSKonstantin Komarov int ntfs_unlink_inode(struct inode *dir, const struct dentry *dentry); 7134534a70bSKonstantin Komarov void ntfs_evict_inode(struct inode *inode); 7144534a70bSKonstantin Komarov extern const struct inode_operations ntfs_link_inode_operations; 7154534a70bSKonstantin Komarov extern const struct address_space_operations ntfs_aops; 7164534a70bSKonstantin Komarov extern const struct address_space_operations ntfs_aops_cmpr; 7174534a70bSKonstantin Komarov 718e8b8e97fSKari Argillander /* Globals from name_i.c */ 7194534a70bSKonstantin Komarov int fill_name_de(struct ntfs_sb_info *sbi, void *buf, const struct qstr *name, 7204534a70bSKonstantin Komarov const struct cpu_str *uni); 7214534a70bSKonstantin Komarov struct dentry *ntfs3_get_parent(struct dentry *child); 7224534a70bSKonstantin Komarov 7234534a70bSKonstantin Komarov extern const struct inode_operations ntfs_dir_inode_operations; 7244534a70bSKonstantin Komarov extern const struct inode_operations ntfs_special_inode_operations; 725a3a956c7SKonstantin Komarov extern const struct dentry_operations ntfs_dentry_ops; 7264534a70bSKonstantin Komarov 727e8b8e97fSKari Argillander /* Globals from record.c */ 7284534a70bSKonstantin Komarov int mi_get(struct ntfs_sb_info *sbi, CLST rno, struct mft_inode **mi); 7294534a70bSKonstantin Komarov void mi_put(struct mft_inode *mi); 7304534a70bSKonstantin Komarov int mi_init(struct mft_inode *mi, struct ntfs_sb_info *sbi, CLST rno); 7314534a70bSKonstantin Komarov int mi_read(struct mft_inode *mi, bool is_mft); 7324534a70bSKonstantin Komarov struct ATTRIB *mi_enum_attr(struct mft_inode *mi, struct ATTRIB *attr); 7334534a70bSKonstantin Komarov // TODO: id? 7344534a70bSKonstantin Komarov struct ATTRIB *mi_find_attr(struct mft_inode *mi, struct ATTRIB *attr, 7354534a70bSKonstantin Komarov enum ATTR_TYPE type, const __le16 *name, 7364534a70bSKonstantin Komarov size_t name_len, const __le16 *id); 7374534a70bSKonstantin Komarov static inline struct ATTRIB *rec_find_attr_le(struct mft_inode *rec, 7384534a70bSKonstantin Komarov struct ATTR_LIST_ENTRY *le) 7394534a70bSKonstantin Komarov { 7404534a70bSKonstantin Komarov return mi_find_attr(rec, NULL, le->type, le_name(le), le->name_len, 7414534a70bSKonstantin Komarov &le->id); 7424534a70bSKonstantin Komarov } 7434534a70bSKonstantin Komarov int mi_write(struct mft_inode *mi, int wait); 7444534a70bSKonstantin Komarov int mi_format_new(struct mft_inode *mi, struct ntfs_sb_info *sbi, CLST rno, 7454534a70bSKonstantin Komarov __le16 flags, bool is_mft); 7464534a70bSKonstantin Komarov struct ATTRIB *mi_insert_attr(struct mft_inode *mi, enum ATTR_TYPE type, 7474534a70bSKonstantin Komarov const __le16 *name, u8 name_len, u32 asize, 7484534a70bSKonstantin Komarov u16 name_off); 7494534a70bSKonstantin Komarov 75078ab59feSKonstantin Komarov bool mi_remove_attr(struct ntfs_inode *ni, struct mft_inode *mi, 75178ab59feSKonstantin Komarov struct ATTRIB *attr); 7524534a70bSKonstantin Komarov bool mi_resize_attr(struct mft_inode *mi, struct ATTRIB *attr, int bytes); 7534534a70bSKonstantin Komarov int mi_pack_runs(struct mft_inode *mi, struct ATTRIB *attr, 7544534a70bSKonstantin Komarov struct runs_tree *run, CLST len); 7554534a70bSKonstantin Komarov static inline bool mi_is_ref(const struct mft_inode *mi, 7564534a70bSKonstantin Komarov const struct MFT_REF *ref) 7574534a70bSKonstantin Komarov { 7584534a70bSKonstantin Komarov if (le32_to_cpu(ref->low) != mi->rno) 7594534a70bSKonstantin Komarov return false; 7604534a70bSKonstantin Komarov if (ref->seq != mi->mrec->seq) 7614534a70bSKonstantin Komarov return false; 7624534a70bSKonstantin Komarov 7634534a70bSKonstantin Komarov #ifdef CONFIG_NTFS3_64BIT_CLUSTER 7644534a70bSKonstantin Komarov return le16_to_cpu(ref->high) == (mi->rno >> 32); 7654534a70bSKonstantin Komarov #else 7664534a70bSKonstantin Komarov return !ref->high; 7674534a70bSKonstantin Komarov #endif 7684534a70bSKonstantin Komarov } 7694534a70bSKonstantin Komarov 7704534a70bSKonstantin Komarov static inline void mi_get_ref(const struct mft_inode *mi, struct MFT_REF *ref) 7714534a70bSKonstantin Komarov { 7724534a70bSKonstantin Komarov ref->low = cpu_to_le32(mi->rno); 7734534a70bSKonstantin Komarov #ifdef CONFIG_NTFS3_64BIT_CLUSTER 7744534a70bSKonstantin Komarov ref->high = cpu_to_le16(mi->rno >> 32); 7754534a70bSKonstantin Komarov #else 7764534a70bSKonstantin Komarov ref->high = 0; 7774534a70bSKonstantin Komarov #endif 7784534a70bSKonstantin Komarov ref->seq = mi->mrec->seq; 7794534a70bSKonstantin Komarov } 7804534a70bSKonstantin Komarov 781e8b8e97fSKari Argillander /* Globals from run.c */ 7824534a70bSKonstantin Komarov bool run_lookup_entry(const struct runs_tree *run, CLST vcn, CLST *lcn, 7834534a70bSKonstantin Komarov CLST *len, size_t *index); 7844534a70bSKonstantin Komarov void run_truncate(struct runs_tree *run, CLST vcn); 7854534a70bSKonstantin Komarov void run_truncate_head(struct runs_tree *run, CLST vcn); 7864534a70bSKonstantin Komarov void run_truncate_around(struct runs_tree *run, CLST vcn); 7874534a70bSKonstantin Komarov bool run_add_entry(struct runs_tree *run, CLST vcn, CLST lcn, CLST len, 7884534a70bSKonstantin Komarov bool is_mft); 7894534a70bSKonstantin Komarov bool run_collapse_range(struct runs_tree *run, CLST vcn, CLST len); 790aa30eccbSKonstantin Komarov bool run_insert_range(struct runs_tree *run, CLST vcn, CLST len); 7914534a70bSKonstantin Komarov bool run_get_entry(const struct runs_tree *run, size_t index, CLST *vcn, 7924534a70bSKonstantin Komarov CLST *lcn, CLST *len); 7934534a70bSKonstantin Komarov bool run_is_mapped_full(const struct runs_tree *run, CLST svcn, CLST evcn); 7944534a70bSKonstantin Komarov 7954534a70bSKonstantin Komarov int run_pack(const struct runs_tree *run, CLST svcn, CLST len, u8 *run_buf, 7964534a70bSKonstantin Komarov u32 run_buf_size, CLST *packed_vcns); 7974534a70bSKonstantin Komarov int run_unpack(struct runs_tree *run, struct ntfs_sb_info *sbi, CLST ino, 7984534a70bSKonstantin Komarov CLST svcn, CLST evcn, CLST vcn, const u8 *run_buf, 7994534a70bSKonstantin Komarov u32 run_buf_size); 8004534a70bSKonstantin Komarov 8014534a70bSKonstantin Komarov #ifdef NTFS3_CHECK_FREE_CLST 8024534a70bSKonstantin Komarov int run_unpack_ex(struct runs_tree *run, struct ntfs_sb_info *sbi, CLST ino, 8034534a70bSKonstantin Komarov CLST svcn, CLST evcn, CLST vcn, const u8 *run_buf, 8044534a70bSKonstantin Komarov u32 run_buf_size); 8054534a70bSKonstantin Komarov #else 8064534a70bSKonstantin Komarov #define run_unpack_ex run_unpack 8074534a70bSKonstantin Komarov #endif 8084534a70bSKonstantin Komarov int run_get_highest_vcn(CLST vcn, const u8 *run_buf, u64 *highest_vcn); 80920abc64fSKonstantin Komarov int run_clone(const struct runs_tree *run, struct runs_tree *new_run); 8104534a70bSKonstantin Komarov 811e8b8e97fSKari Argillander /* Globals from super.c */ 8124534a70bSKonstantin Komarov void *ntfs_set_shared(void *ptr, u32 bytes); 8134534a70bSKonstantin Komarov void *ntfs_put_shared(void *ptr); 8144534a70bSKonstantin Komarov void ntfs_unmap_meta(struct super_block *sb, CLST lcn, CLST len); 8154534a70bSKonstantin Komarov int ntfs_discard(struct ntfs_sb_info *sbi, CLST Lcn, CLST Len); 8164534a70bSKonstantin Komarov 817e8b8e97fSKari Argillander /* Globals from bitmap.c*/ 8184534a70bSKonstantin Komarov int __init ntfs3_init_bitmap(void); 8194534a70bSKonstantin Komarov void ntfs3_exit_bitmap(void); 8204534a70bSKonstantin Komarov void wnd_close(struct wnd_bitmap *wnd); 8214534a70bSKonstantin Komarov static inline size_t wnd_zeroes(const struct wnd_bitmap *wnd) 8224534a70bSKonstantin Komarov { 8234534a70bSKonstantin Komarov return wnd->total_zeroes; 8244534a70bSKonstantin Komarov } 8254534a70bSKonstantin Komarov int wnd_init(struct wnd_bitmap *wnd, struct super_block *sb, size_t nbits); 8264534a70bSKonstantin Komarov int wnd_set_free(struct wnd_bitmap *wnd, size_t bit, size_t bits); 8274534a70bSKonstantin Komarov int wnd_set_used(struct wnd_bitmap *wnd, size_t bit, size_t bits); 8284534a70bSKonstantin Komarov bool wnd_is_free(struct wnd_bitmap *wnd, size_t bit, size_t bits); 8294534a70bSKonstantin Komarov bool wnd_is_used(struct wnd_bitmap *wnd, size_t bit, size_t bits); 8304534a70bSKonstantin Komarov 831e8b8e97fSKari Argillander /* Possible values for 'flags' 'wnd_find'. */ 8324534a70bSKonstantin Komarov #define BITMAP_FIND_MARK_AS_USED 0x01 8334534a70bSKonstantin Komarov #define BITMAP_FIND_FULL 0x02 8344534a70bSKonstantin Komarov size_t wnd_find(struct wnd_bitmap *wnd, size_t to_alloc, size_t hint, 8354534a70bSKonstantin Komarov size_t flags, size_t *allocated); 8364534a70bSKonstantin Komarov int wnd_extend(struct wnd_bitmap *wnd, size_t new_bits); 8374534a70bSKonstantin Komarov void wnd_zone_set(struct wnd_bitmap *wnd, size_t Lcn, size_t Len); 8384534a70bSKonstantin Komarov int ntfs_trim_fs(struct ntfs_sb_info *sbi, struct fstrim_range *range); 8394534a70bSKonstantin Komarov 84008811ba5SKonstantin Komarov void ntfs_bitmap_set_le(void *map, unsigned int start, int len); 84108811ba5SKonstantin Komarov void ntfs_bitmap_clear_le(void *map, unsigned int start, int len); 84208811ba5SKonstantin Komarov unsigned int ntfs_bitmap_weight_le(const void *bitmap, int bits); 84388a8d0d2SThomas Kühnel 844e8b8e97fSKari Argillander /* Globals from upcase.c */ 8454534a70bSKonstantin Komarov int ntfs_cmp_names(const __le16 *s1, size_t l1, const __le16 *s2, size_t l2, 8464534a70bSKonstantin Komarov const u16 *upcase, bool bothcase); 8474534a70bSKonstantin Komarov int ntfs_cmp_names_cpu(const struct cpu_str *uni1, const struct le_str *uni2, 8484534a70bSKonstantin Komarov const u16 *upcase, bool bothcase); 849a3a956c7SKonstantin Komarov unsigned long ntfs_names_hash(const u16 *name, size_t len, const u16 *upcase, 850a3a956c7SKonstantin Komarov unsigned long hash); 8514534a70bSKonstantin Komarov 8524534a70bSKonstantin Komarov /* globals from xattr.c */ 8534534a70bSKonstantin Komarov #ifdef CONFIG_NTFS3_FS_POSIX_ACL 854f7464060SLinus Torvalds struct posix_acl *ntfs_get_acl(struct inode *inode, int type, bool rcu); 8554534a70bSKonstantin Komarov int ntfs_set_acl(struct user_namespace *mnt_userns, struct inode *inode, 8564534a70bSKonstantin Komarov struct posix_acl *acl, int type); 8574534a70bSKonstantin Komarov int ntfs_init_acl(struct user_namespace *mnt_userns, struct inode *inode, 8584534a70bSKonstantin Komarov struct inode *dir); 8594534a70bSKonstantin Komarov #else 8604534a70bSKonstantin Komarov #define ntfs_get_acl NULL 8614534a70bSKonstantin Komarov #define ntfs_set_acl NULL 8624534a70bSKonstantin Komarov #endif 8634534a70bSKonstantin Komarov 8644534a70bSKonstantin Komarov int ntfs_acl_chmod(struct user_namespace *mnt_userns, struct inode *inode); 8654534a70bSKonstantin Komarov int ntfs_permission(struct user_namespace *mnt_userns, struct inode *inode, 8664534a70bSKonstantin Komarov int mask); 8674534a70bSKonstantin Komarov ssize_t ntfs_listxattr(struct dentry *dentry, char *buffer, size_t size); 8684534a70bSKonstantin Komarov extern const struct xattr_handler *ntfs_xattr_handlers[]; 8694534a70bSKonstantin Komarov 8704534a70bSKonstantin Komarov int ntfs_save_wsl_perm(struct inode *inode); 8714534a70bSKonstantin Komarov void ntfs_get_wsl_perm(struct inode *inode); 8724534a70bSKonstantin Komarov 8734534a70bSKonstantin Komarov /* globals from lznt.c */ 8744534a70bSKonstantin Komarov struct lznt *get_lznt_ctx(int level); 8754534a70bSKonstantin Komarov size_t compress_lznt(const void *uncompressed, size_t uncompressed_size, 8764534a70bSKonstantin Komarov void *compressed, size_t compressed_size, 8774534a70bSKonstantin Komarov struct lznt *ctx); 8784534a70bSKonstantin Komarov ssize_t decompress_lznt(const void *compressed, size_t compressed_size, 8794534a70bSKonstantin Komarov void *uncompressed, size_t uncompressed_size); 8804534a70bSKonstantin Komarov 8814534a70bSKonstantin Komarov static inline bool is_ntfs3(struct ntfs_sb_info *sbi) 8824534a70bSKonstantin Komarov { 8834534a70bSKonstantin Komarov return sbi->volume.major_ver >= 3; 8844534a70bSKonstantin Komarov } 8854534a70bSKonstantin Komarov 8864534a70bSKonstantin Komarov /* (sb->s_flags & SB_ACTIVE) */ 8874534a70bSKonstantin Komarov static inline bool is_mounted(struct ntfs_sb_info *sbi) 8884534a70bSKonstantin Komarov { 8894534a70bSKonstantin Komarov return !!sbi->sb->s_root; 8904534a70bSKonstantin Komarov } 8914534a70bSKonstantin Komarov 8924534a70bSKonstantin Komarov static inline bool ntfs_is_meta_file(struct ntfs_sb_info *sbi, CLST rno) 8934534a70bSKonstantin Komarov { 8944534a70bSKonstantin Komarov return rno < MFT_REC_FREE || rno == sbi->objid_no || 8954534a70bSKonstantin Komarov rno == sbi->quota_no || rno == sbi->reparse_no || 8964534a70bSKonstantin Komarov rno == sbi->usn_jrnl_no; 8974534a70bSKonstantin Komarov } 8984534a70bSKonstantin Komarov 8994534a70bSKonstantin Komarov static inline void ntfs_unmap_page(struct page *page) 9004534a70bSKonstantin Komarov { 9014534a70bSKonstantin Komarov kunmap(page); 9024534a70bSKonstantin Komarov put_page(page); 9034534a70bSKonstantin Komarov } 9044534a70bSKonstantin Komarov 9054534a70bSKonstantin Komarov static inline struct page *ntfs_map_page(struct address_space *mapping, 9064534a70bSKonstantin Komarov unsigned long index) 9074534a70bSKonstantin Komarov { 9084534a70bSKonstantin Komarov struct page *page = read_mapping_page(mapping, index, NULL); 9094534a70bSKonstantin Komarov 91019cb4273SMatthew Wilcox (Oracle) if (!IS_ERR(page)) 9114534a70bSKonstantin Komarov kmap(page); 9124534a70bSKonstantin Komarov return page; 9134534a70bSKonstantin Komarov } 9144534a70bSKonstantin Komarov 9154534a70bSKonstantin Komarov static inline size_t wnd_zone_bit(const struct wnd_bitmap *wnd) 9164534a70bSKonstantin Komarov { 9174534a70bSKonstantin Komarov return wnd->zone_bit; 9184534a70bSKonstantin Komarov } 9194534a70bSKonstantin Komarov 9204534a70bSKonstantin Komarov static inline size_t wnd_zone_len(const struct wnd_bitmap *wnd) 9214534a70bSKonstantin Komarov { 9224534a70bSKonstantin Komarov return wnd->zone_end - wnd->zone_bit; 9234534a70bSKonstantin Komarov } 9244534a70bSKonstantin Komarov 9254534a70bSKonstantin Komarov static inline void run_init(struct runs_tree *run) 9264534a70bSKonstantin Komarov { 9274534a70bSKonstantin Komarov run->runs = NULL; 9284534a70bSKonstantin Komarov run->count = 0; 9294534a70bSKonstantin Komarov run->allocated = 0; 9304534a70bSKonstantin Komarov } 9314534a70bSKonstantin Komarov 9324534a70bSKonstantin Komarov static inline struct runs_tree *run_alloc(void) 9334534a70bSKonstantin Komarov { 934195c52bdSKari Argillander return kzalloc(sizeof(struct runs_tree), GFP_NOFS); 9354534a70bSKonstantin Komarov } 9364534a70bSKonstantin Komarov 9374534a70bSKonstantin Komarov static inline void run_close(struct runs_tree *run) 9384534a70bSKonstantin Komarov { 939195c52bdSKari Argillander kvfree(run->runs); 9404534a70bSKonstantin Komarov memset(run, 0, sizeof(*run)); 9414534a70bSKonstantin Komarov } 9424534a70bSKonstantin Komarov 9434534a70bSKonstantin Komarov static inline void run_free(struct runs_tree *run) 9444534a70bSKonstantin Komarov { 9454534a70bSKonstantin Komarov if (run) { 946195c52bdSKari Argillander kvfree(run->runs); 947195c52bdSKari Argillander kfree(run); 9484534a70bSKonstantin Komarov } 9494534a70bSKonstantin Komarov } 9504534a70bSKonstantin Komarov 9514534a70bSKonstantin Komarov static inline bool run_is_empty(struct runs_tree *run) 9524534a70bSKonstantin Komarov { 9534534a70bSKonstantin Komarov return !run->count; 9544534a70bSKonstantin Komarov } 9554534a70bSKonstantin Komarov 956e8b8e97fSKari Argillander /* NTFS uses quad aligned bitmaps. */ 9574534a70bSKonstantin Komarov static inline size_t bitmap_size(size_t bits) 9584534a70bSKonstantin Komarov { 959fa3cacf5SKari Argillander return ALIGN((bits + 7) >> 3, 8); 9604534a70bSKonstantin Komarov } 9614534a70bSKonstantin Komarov 9624534a70bSKonstantin Komarov #define _100ns2seconds 10000000 9634534a70bSKonstantin Komarov #define SecondsToStartOf1970 0x00000002B6109100 9644534a70bSKonstantin Komarov 9654534a70bSKonstantin Komarov #define NTFS_TIME_GRAN 100 9664534a70bSKonstantin Komarov 9674534a70bSKonstantin Komarov /* 968e8b8e97fSKari Argillander * kernel2nt - Converts in-memory kernel timestamp into nt time. 9694534a70bSKonstantin Komarov */ 9704534a70bSKonstantin Komarov static inline __le64 kernel2nt(const struct timespec64 *ts) 9714534a70bSKonstantin Komarov { 9724534a70bSKonstantin Komarov // 10^7 units of 100 nanoseconds one second 9734534a70bSKonstantin Komarov return cpu_to_le64(_100ns2seconds * 9744534a70bSKonstantin Komarov (ts->tv_sec + SecondsToStartOf1970) + 9754534a70bSKonstantin Komarov ts->tv_nsec / NTFS_TIME_GRAN); 9764534a70bSKonstantin Komarov } 9774534a70bSKonstantin Komarov 9784534a70bSKonstantin Komarov /* 979e8b8e97fSKari Argillander * nt2kernel - Converts on-disk nt time into kernel timestamp. 9804534a70bSKonstantin Komarov */ 9814534a70bSKonstantin Komarov static inline void nt2kernel(const __le64 tm, struct timespec64 *ts) 9824534a70bSKonstantin Komarov { 9834534a70bSKonstantin Komarov u64 t = le64_to_cpu(tm) - _100ns2seconds * SecondsToStartOf1970; 9844534a70bSKonstantin Komarov 9854534a70bSKonstantin Komarov // WARNING: do_div changes its first argument(!) 9864534a70bSKonstantin Komarov ts->tv_nsec = do_div(t, _100ns2seconds) * 100; 9874534a70bSKonstantin Komarov ts->tv_sec = t; 9884534a70bSKonstantin Komarov } 9894534a70bSKonstantin Komarov 9904534a70bSKonstantin Komarov static inline struct ntfs_sb_info *ntfs_sb(struct super_block *sb) 9914534a70bSKonstantin Komarov { 9924534a70bSKonstantin Komarov return sb->s_fs_info; 9934534a70bSKonstantin Komarov } 9944534a70bSKonstantin Komarov 995e8b8e97fSKari Argillander /* 996e8b8e97fSKari Argillander * ntfs_up_cluster - Align up on cluster boundary. 997e8b8e97fSKari Argillander */ 9984534a70bSKonstantin Komarov static inline u64 ntfs_up_cluster(const struct ntfs_sb_info *sbi, u64 size) 9994534a70bSKonstantin Komarov { 10004534a70bSKonstantin Komarov return (size + sbi->cluster_mask) & sbi->cluster_mask_inv; 10014534a70bSKonstantin Komarov } 10024534a70bSKonstantin Komarov 1003e8b8e97fSKari Argillander /* 1004e8b8e97fSKari Argillander * ntfs_up_block - Align up on cluster boundary. 1005e8b8e97fSKari Argillander */ 10064534a70bSKonstantin Komarov static inline u64 ntfs_up_block(const struct super_block *sb, u64 size) 10074534a70bSKonstantin Komarov { 10084534a70bSKonstantin Komarov return (size + sb->s_blocksize - 1) & ~(u64)(sb->s_blocksize - 1); 10094534a70bSKonstantin Komarov } 10104534a70bSKonstantin Komarov 10114534a70bSKonstantin Komarov static inline CLST bytes_to_cluster(const struct ntfs_sb_info *sbi, u64 size) 10124534a70bSKonstantin Komarov { 10134534a70bSKonstantin Komarov return (size + sbi->cluster_mask) >> sbi->cluster_bits; 10144534a70bSKonstantin Komarov } 10154534a70bSKonstantin Komarov 10164534a70bSKonstantin Komarov static inline u64 bytes_to_block(const struct super_block *sb, u64 size) 10174534a70bSKonstantin Komarov { 10184534a70bSKonstantin Komarov return (size + sb->s_blocksize - 1) >> sb->s_blocksize_bits; 10194534a70bSKonstantin Komarov } 10204534a70bSKonstantin Komarov 10214534a70bSKonstantin Komarov static inline struct buffer_head *ntfs_bread(struct super_block *sb, 10224534a70bSKonstantin Komarov sector_t block) 10234534a70bSKonstantin Komarov { 10244534a70bSKonstantin Komarov struct buffer_head *bh = sb_bread(sb, block); 10254534a70bSKonstantin Komarov 10264534a70bSKonstantin Komarov if (bh) 10274534a70bSKonstantin Komarov return bh; 10284534a70bSKonstantin Komarov 10294534a70bSKonstantin Komarov ntfs_err(sb, "failed to read volume at offset 0x%llx", 10304534a70bSKonstantin Komarov (u64)block << sb->s_blocksize_bits); 10314534a70bSKonstantin Komarov return NULL; 10324534a70bSKonstantin Komarov } 10334534a70bSKonstantin Komarov 10344534a70bSKonstantin Komarov static inline struct ntfs_inode *ntfs_i(struct inode *inode) 10354534a70bSKonstantin Komarov { 10364534a70bSKonstantin Komarov return container_of(inode, struct ntfs_inode, vfs_inode); 10374534a70bSKonstantin Komarov } 10384534a70bSKonstantin Komarov 10394534a70bSKonstantin Komarov static inline bool is_compressed(const struct ntfs_inode *ni) 10404534a70bSKonstantin Komarov { 10414534a70bSKonstantin Komarov return (ni->std_fa & FILE_ATTRIBUTE_COMPRESSED) || 10424534a70bSKonstantin Komarov (ni->ni_flags & NI_FLAG_COMPRESSED_MASK); 10434534a70bSKonstantin Komarov } 10444534a70bSKonstantin Komarov 10454534a70bSKonstantin Komarov static inline int ni_ext_compress_bits(const struct ntfs_inode *ni) 10464534a70bSKonstantin Komarov { 10474534a70bSKonstantin Komarov return 0xb + (ni->ni_flags & NI_FLAG_COMPRESSED_MASK); 10484534a70bSKonstantin Komarov } 10494534a70bSKonstantin Komarov 1050e8b8e97fSKari Argillander /* Bits - 0xc, 0xd, 0xe, 0xf, 0x10 */ 10514534a70bSKonstantin Komarov static inline void ni_set_ext_compress_bits(struct ntfs_inode *ni, u8 bits) 10524534a70bSKonstantin Komarov { 10534534a70bSKonstantin Komarov ni->ni_flags |= (bits - 0xb) & NI_FLAG_COMPRESSED_MASK; 10544534a70bSKonstantin Komarov } 10554534a70bSKonstantin Komarov 10564534a70bSKonstantin Komarov static inline bool is_dedup(const struct ntfs_inode *ni) 10574534a70bSKonstantin Komarov { 10584534a70bSKonstantin Komarov return ni->ni_flags & NI_FLAG_DEDUPLICATED; 10594534a70bSKonstantin Komarov } 10604534a70bSKonstantin Komarov 10614534a70bSKonstantin Komarov static inline bool is_encrypted(const struct ntfs_inode *ni) 10624534a70bSKonstantin Komarov { 10634534a70bSKonstantin Komarov return ni->std_fa & FILE_ATTRIBUTE_ENCRYPTED; 10644534a70bSKonstantin Komarov } 10654534a70bSKonstantin Komarov 10664534a70bSKonstantin Komarov static inline bool is_sparsed(const struct ntfs_inode *ni) 10674534a70bSKonstantin Komarov { 10684534a70bSKonstantin Komarov return ni->std_fa & FILE_ATTRIBUTE_SPARSE_FILE; 10694534a70bSKonstantin Komarov } 10704534a70bSKonstantin Komarov 10714534a70bSKonstantin Komarov static inline int is_resident(struct ntfs_inode *ni) 10724534a70bSKonstantin Komarov { 10734534a70bSKonstantin Komarov return ni->ni_flags & NI_FLAG_RESIDENT; 10744534a70bSKonstantin Komarov } 10754534a70bSKonstantin Komarov 10764534a70bSKonstantin Komarov static inline void le16_sub_cpu(__le16 *var, u16 val) 10774534a70bSKonstantin Komarov { 10784534a70bSKonstantin Komarov *var = cpu_to_le16(le16_to_cpu(*var) - val); 10794534a70bSKonstantin Komarov } 10804534a70bSKonstantin Komarov 10814534a70bSKonstantin Komarov static inline void le32_sub_cpu(__le32 *var, u32 val) 10824534a70bSKonstantin Komarov { 10834534a70bSKonstantin Komarov *var = cpu_to_le32(le32_to_cpu(*var) - val); 10844534a70bSKonstantin Komarov } 10854534a70bSKonstantin Komarov 10864534a70bSKonstantin Komarov static inline void nb_put(struct ntfs_buffers *nb) 10874534a70bSKonstantin Komarov { 10884534a70bSKonstantin Komarov u32 i, nbufs = nb->nbufs; 10894534a70bSKonstantin Komarov 10904534a70bSKonstantin Komarov if (!nbufs) 10914534a70bSKonstantin Komarov return; 10924534a70bSKonstantin Komarov 10934534a70bSKonstantin Komarov for (i = 0; i < nbufs; i++) 10944534a70bSKonstantin Komarov put_bh(nb->bh[i]); 10954534a70bSKonstantin Komarov nb->nbufs = 0; 10964534a70bSKonstantin Komarov } 10974534a70bSKonstantin Komarov 10984534a70bSKonstantin Komarov static inline void put_indx_node(struct indx_node *in) 10994534a70bSKonstantin Komarov { 11004534a70bSKonstantin Komarov if (!in) 11014534a70bSKonstantin Komarov return; 11024534a70bSKonstantin Komarov 1103195c52bdSKari Argillander kfree(in->index); 11044534a70bSKonstantin Komarov nb_put(&in->nb); 1105195c52bdSKari Argillander kfree(in); 11064534a70bSKonstantin Komarov } 11074534a70bSKonstantin Komarov 11084534a70bSKonstantin Komarov static inline void mi_clear(struct mft_inode *mi) 11094534a70bSKonstantin Komarov { 11104534a70bSKonstantin Komarov nb_put(&mi->nb); 1111195c52bdSKari Argillander kfree(mi->mrec); 11124534a70bSKonstantin Komarov mi->mrec = NULL; 11134534a70bSKonstantin Komarov } 11144534a70bSKonstantin Komarov 11154534a70bSKonstantin Komarov static inline void ni_lock(struct ntfs_inode *ni) 11164534a70bSKonstantin Komarov { 11174534a70bSKonstantin Komarov mutex_lock_nested(&ni->ni_lock, NTFS_INODE_MUTEX_NORMAL); 11184534a70bSKonstantin Komarov } 11194534a70bSKonstantin Komarov 11204534a70bSKonstantin Komarov static inline void ni_lock_dir(struct ntfs_inode *ni) 11214534a70bSKonstantin Komarov { 11224534a70bSKonstantin Komarov mutex_lock_nested(&ni->ni_lock, NTFS_INODE_MUTEX_PARENT); 11234534a70bSKonstantin Komarov } 11244534a70bSKonstantin Komarov 1125*0ad9dfcbSKonstantin Komarov static inline void ni_lock_dir2(struct ntfs_inode *ni) 1126*0ad9dfcbSKonstantin Komarov { 1127*0ad9dfcbSKonstantin Komarov mutex_lock_nested(&ni->ni_lock, NTFS_INODE_MUTEX_PARENT2); 1128*0ad9dfcbSKonstantin Komarov } 1129*0ad9dfcbSKonstantin Komarov 11304534a70bSKonstantin Komarov static inline void ni_unlock(struct ntfs_inode *ni) 11314534a70bSKonstantin Komarov { 11324534a70bSKonstantin Komarov mutex_unlock(&ni->ni_lock); 11334534a70bSKonstantin Komarov } 11344534a70bSKonstantin Komarov 11354534a70bSKonstantin Komarov static inline int ni_trylock(struct ntfs_inode *ni) 11364534a70bSKonstantin Komarov { 11374534a70bSKonstantin Komarov return mutex_trylock(&ni->ni_lock); 11384534a70bSKonstantin Komarov } 11394534a70bSKonstantin Komarov 11404534a70bSKonstantin Komarov static inline int attr_load_runs_attr(struct ntfs_inode *ni, 11414534a70bSKonstantin Komarov struct ATTRIB *attr, 11424534a70bSKonstantin Komarov struct runs_tree *run, CLST vcn) 11434534a70bSKonstantin Komarov { 11444534a70bSKonstantin Komarov return attr_load_runs_vcn(ni, attr->type, attr_name(attr), 11454534a70bSKonstantin Komarov attr->name_len, run, vcn); 11464534a70bSKonstantin Komarov } 11474534a70bSKonstantin Komarov 11484534a70bSKonstantin Komarov static inline void le64_sub_cpu(__le64 *var, u64 val) 11494534a70bSKonstantin Komarov { 11504534a70bSKonstantin Komarov *var = cpu_to_le64(le64_to_cpu(*var) - val); 11514534a70bSKonstantin Komarov } 115287790b65SKari Argillander 115387790b65SKari Argillander #endif /* _LINUX_NTFS3_NTFS_FS_H */ 1154