162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-or-later */ 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * inode.h - Defines for inode structures NTFS Linux kernel driver. Part of 462306a36Sopenharmony_ci * the Linux-NTFS project. 562306a36Sopenharmony_ci * 662306a36Sopenharmony_ci * Copyright (c) 2001-2007 Anton Altaparmakov 762306a36Sopenharmony_ci * Copyright (c) 2002 Richard Russon 862306a36Sopenharmony_ci */ 962306a36Sopenharmony_ci 1062306a36Sopenharmony_ci#ifndef _LINUX_NTFS_INODE_H 1162306a36Sopenharmony_ci#define _LINUX_NTFS_INODE_H 1262306a36Sopenharmony_ci 1362306a36Sopenharmony_ci#include <linux/atomic.h> 1462306a36Sopenharmony_ci 1562306a36Sopenharmony_ci#include <linux/fs.h> 1662306a36Sopenharmony_ci#include <linux/list.h> 1762306a36Sopenharmony_ci#include <linux/mm.h> 1862306a36Sopenharmony_ci#include <linux/mutex.h> 1962306a36Sopenharmony_ci#include <linux/seq_file.h> 2062306a36Sopenharmony_ci 2162306a36Sopenharmony_ci#include "layout.h" 2262306a36Sopenharmony_ci#include "volume.h" 2362306a36Sopenharmony_ci#include "types.h" 2462306a36Sopenharmony_ci#include "runlist.h" 2562306a36Sopenharmony_ci#include "debug.h" 2662306a36Sopenharmony_ci 2762306a36Sopenharmony_citypedef struct _ntfs_inode ntfs_inode; 2862306a36Sopenharmony_ci 2962306a36Sopenharmony_ci/* 3062306a36Sopenharmony_ci * The NTFS in-memory inode structure. It is just used as an extension to the 3162306a36Sopenharmony_ci * fields already provided in the VFS inode. 3262306a36Sopenharmony_ci */ 3362306a36Sopenharmony_cistruct _ntfs_inode { 3462306a36Sopenharmony_ci rwlock_t size_lock; /* Lock serializing access to inode sizes. */ 3562306a36Sopenharmony_ci s64 initialized_size; /* Copy from the attribute record. */ 3662306a36Sopenharmony_ci s64 allocated_size; /* Copy from the attribute record. */ 3762306a36Sopenharmony_ci unsigned long state; /* NTFS specific flags describing this inode. 3862306a36Sopenharmony_ci See ntfs_inode_state_bits below. */ 3962306a36Sopenharmony_ci unsigned long mft_no; /* Number of the mft record / inode. */ 4062306a36Sopenharmony_ci u16 seq_no; /* Sequence number of the mft record. */ 4162306a36Sopenharmony_ci atomic_t count; /* Inode reference count for book keeping. */ 4262306a36Sopenharmony_ci ntfs_volume *vol; /* Pointer to the ntfs volume of this inode. */ 4362306a36Sopenharmony_ci /* 4462306a36Sopenharmony_ci * If NInoAttr() is true, the below fields describe the attribute which 4562306a36Sopenharmony_ci * this fake inode belongs to. The actual inode of this attribute is 4662306a36Sopenharmony_ci * pointed to by base_ntfs_ino and nr_extents is always set to -1 (see 4762306a36Sopenharmony_ci * below). For real inodes, we also set the type (AT_DATA for files and 4862306a36Sopenharmony_ci * AT_INDEX_ALLOCATION for directories), with the name = NULL and 4962306a36Sopenharmony_ci * name_len = 0 for files and name = I30 (global constant) and 5062306a36Sopenharmony_ci * name_len = 4 for directories. 5162306a36Sopenharmony_ci */ 5262306a36Sopenharmony_ci ATTR_TYPE type; /* Attribute type of this fake inode. */ 5362306a36Sopenharmony_ci ntfschar *name; /* Attribute name of this fake inode. */ 5462306a36Sopenharmony_ci u32 name_len; /* Attribute name length of this fake inode. */ 5562306a36Sopenharmony_ci runlist runlist; /* If state has the NI_NonResident bit set, 5662306a36Sopenharmony_ci the runlist of the unnamed data attribute 5762306a36Sopenharmony_ci (if a file) or of the index allocation 5862306a36Sopenharmony_ci attribute (directory) or of the attribute 5962306a36Sopenharmony_ci described by the fake inode (if NInoAttr()). 6062306a36Sopenharmony_ci If runlist.rl is NULL, the runlist has not 6162306a36Sopenharmony_ci been read in yet or has been unmapped. If 6262306a36Sopenharmony_ci NI_NonResident is clear, the attribute is 6362306a36Sopenharmony_ci resident (file and fake inode) or there is 6462306a36Sopenharmony_ci no $I30 index allocation attribute 6562306a36Sopenharmony_ci (small directory). In the latter case 6662306a36Sopenharmony_ci runlist.rl is always NULL.*/ 6762306a36Sopenharmony_ci /* 6862306a36Sopenharmony_ci * The following fields are only valid for real inodes and extent 6962306a36Sopenharmony_ci * inodes. 7062306a36Sopenharmony_ci */ 7162306a36Sopenharmony_ci struct mutex mrec_lock; /* Lock for serializing access to the 7262306a36Sopenharmony_ci mft record belonging to this inode. */ 7362306a36Sopenharmony_ci struct page *page; /* The page containing the mft record of the 7462306a36Sopenharmony_ci inode. This should only be touched by the 7562306a36Sopenharmony_ci (un)map_mft_record*() functions. */ 7662306a36Sopenharmony_ci int page_ofs; /* Offset into the page at which the mft record 7762306a36Sopenharmony_ci begins. This should only be touched by the 7862306a36Sopenharmony_ci (un)map_mft_record*() functions. */ 7962306a36Sopenharmony_ci /* 8062306a36Sopenharmony_ci * Attribute list support (only for use by the attribute lookup 8162306a36Sopenharmony_ci * functions). Setup during read_inode for all inodes with attribute 8262306a36Sopenharmony_ci * lists. Only valid if NI_AttrList is set in state, and attr_list_rl is 8362306a36Sopenharmony_ci * further only valid if NI_AttrListNonResident is set. 8462306a36Sopenharmony_ci */ 8562306a36Sopenharmony_ci u32 attr_list_size; /* Length of attribute list value in bytes. */ 8662306a36Sopenharmony_ci u8 *attr_list; /* Attribute list value itself. */ 8762306a36Sopenharmony_ci runlist attr_list_rl; /* Run list for the attribute list value. */ 8862306a36Sopenharmony_ci union { 8962306a36Sopenharmony_ci struct { /* It is a directory, $MFT, or an index inode. */ 9062306a36Sopenharmony_ci u32 block_size; /* Size of an index block. */ 9162306a36Sopenharmony_ci u32 vcn_size; /* Size of a vcn in this 9262306a36Sopenharmony_ci index. */ 9362306a36Sopenharmony_ci COLLATION_RULE collation_rule; /* The collation rule 9462306a36Sopenharmony_ci for the index. */ 9562306a36Sopenharmony_ci u8 block_size_bits; /* Log2 of the above. */ 9662306a36Sopenharmony_ci u8 vcn_size_bits; /* Log2 of the above. */ 9762306a36Sopenharmony_ci } index; 9862306a36Sopenharmony_ci struct { /* It is a compressed/sparse file/attribute inode. */ 9962306a36Sopenharmony_ci s64 size; /* Copy of compressed_size from 10062306a36Sopenharmony_ci $DATA. */ 10162306a36Sopenharmony_ci u32 block_size; /* Size of a compression block 10262306a36Sopenharmony_ci (cb). */ 10362306a36Sopenharmony_ci u8 block_size_bits; /* Log2 of the size of a cb. */ 10462306a36Sopenharmony_ci u8 block_clusters; /* Number of clusters per cb. */ 10562306a36Sopenharmony_ci } compressed; 10662306a36Sopenharmony_ci } itype; 10762306a36Sopenharmony_ci struct mutex extent_lock; /* Lock for accessing/modifying the 10862306a36Sopenharmony_ci below . */ 10962306a36Sopenharmony_ci s32 nr_extents; /* For a base mft record, the number of attached extent 11062306a36Sopenharmony_ci inodes (0 if none), for extent records and for fake 11162306a36Sopenharmony_ci inodes describing an attribute this is -1. */ 11262306a36Sopenharmony_ci union { /* This union is only used if nr_extents != 0. */ 11362306a36Sopenharmony_ci ntfs_inode **extent_ntfs_inos; /* For nr_extents > 0, array of 11462306a36Sopenharmony_ci the ntfs inodes of the extent 11562306a36Sopenharmony_ci mft records belonging to 11662306a36Sopenharmony_ci this base inode which have 11762306a36Sopenharmony_ci been loaded. */ 11862306a36Sopenharmony_ci ntfs_inode *base_ntfs_ino; /* For nr_extents == -1, the 11962306a36Sopenharmony_ci ntfs inode of the base mft 12062306a36Sopenharmony_ci record. For fake inodes, the 12162306a36Sopenharmony_ci real (base) inode to which 12262306a36Sopenharmony_ci the attribute belongs. */ 12362306a36Sopenharmony_ci } ext; 12462306a36Sopenharmony_ci}; 12562306a36Sopenharmony_ci 12662306a36Sopenharmony_ci/* 12762306a36Sopenharmony_ci * Defined bits for the state field in the ntfs_inode structure. 12862306a36Sopenharmony_ci * (f) = files only, (d) = directories only, (a) = attributes/fake inodes only 12962306a36Sopenharmony_ci */ 13062306a36Sopenharmony_citypedef enum { 13162306a36Sopenharmony_ci NI_Dirty, /* 1: Mft record needs to be written to disk. */ 13262306a36Sopenharmony_ci NI_AttrList, /* 1: Mft record contains an attribute list. */ 13362306a36Sopenharmony_ci NI_AttrListNonResident, /* 1: Attribute list is non-resident. Implies 13462306a36Sopenharmony_ci NI_AttrList is set. */ 13562306a36Sopenharmony_ci 13662306a36Sopenharmony_ci NI_Attr, /* 1: Fake inode for attribute i/o. 13762306a36Sopenharmony_ci 0: Real inode or extent inode. */ 13862306a36Sopenharmony_ci 13962306a36Sopenharmony_ci NI_MstProtected, /* 1: Attribute is protected by MST fixups. 14062306a36Sopenharmony_ci 0: Attribute is not protected by fixups. */ 14162306a36Sopenharmony_ci NI_NonResident, /* 1: Unnamed data attr is non-resident (f). 14262306a36Sopenharmony_ci 1: Attribute is non-resident (a). */ 14362306a36Sopenharmony_ci NI_IndexAllocPresent = NI_NonResident, /* 1: $I30 index alloc attr is 14462306a36Sopenharmony_ci present (d). */ 14562306a36Sopenharmony_ci NI_Compressed, /* 1: Unnamed data attr is compressed (f). 14662306a36Sopenharmony_ci 1: Create compressed files by default (d). 14762306a36Sopenharmony_ci 1: Attribute is compressed (a). */ 14862306a36Sopenharmony_ci NI_Encrypted, /* 1: Unnamed data attr is encrypted (f). 14962306a36Sopenharmony_ci 1: Create encrypted files by default (d). 15062306a36Sopenharmony_ci 1: Attribute is encrypted (a). */ 15162306a36Sopenharmony_ci NI_Sparse, /* 1: Unnamed data attr is sparse (f). 15262306a36Sopenharmony_ci 1: Create sparse files by default (d). 15362306a36Sopenharmony_ci 1: Attribute is sparse (a). */ 15462306a36Sopenharmony_ci NI_SparseDisabled, /* 1: May not create sparse regions. */ 15562306a36Sopenharmony_ci NI_TruncateFailed, /* 1: Last ntfs_truncate() call failed. */ 15662306a36Sopenharmony_ci} ntfs_inode_state_bits; 15762306a36Sopenharmony_ci 15862306a36Sopenharmony_ci/* 15962306a36Sopenharmony_ci * NOTE: We should be adding dirty mft records to a list somewhere and they 16062306a36Sopenharmony_ci * should be independent of the (ntfs/vfs) inode structure so that an inode can 16162306a36Sopenharmony_ci * be removed but the record can be left dirty for syncing later. 16262306a36Sopenharmony_ci */ 16362306a36Sopenharmony_ci 16462306a36Sopenharmony_ci/* 16562306a36Sopenharmony_ci * Macro tricks to expand the NInoFoo(), NInoSetFoo(), and NInoClearFoo() 16662306a36Sopenharmony_ci * functions. 16762306a36Sopenharmony_ci */ 16862306a36Sopenharmony_ci#define NINO_FNS(flag) \ 16962306a36Sopenharmony_cistatic inline int NIno##flag(ntfs_inode *ni) \ 17062306a36Sopenharmony_ci{ \ 17162306a36Sopenharmony_ci return test_bit(NI_##flag, &(ni)->state); \ 17262306a36Sopenharmony_ci} \ 17362306a36Sopenharmony_cistatic inline void NInoSet##flag(ntfs_inode *ni) \ 17462306a36Sopenharmony_ci{ \ 17562306a36Sopenharmony_ci set_bit(NI_##flag, &(ni)->state); \ 17662306a36Sopenharmony_ci} \ 17762306a36Sopenharmony_cistatic inline void NInoClear##flag(ntfs_inode *ni) \ 17862306a36Sopenharmony_ci{ \ 17962306a36Sopenharmony_ci clear_bit(NI_##flag, &(ni)->state); \ 18062306a36Sopenharmony_ci} 18162306a36Sopenharmony_ci 18262306a36Sopenharmony_ci/* 18362306a36Sopenharmony_ci * As above for NInoTestSetFoo() and NInoTestClearFoo(). 18462306a36Sopenharmony_ci */ 18562306a36Sopenharmony_ci#define TAS_NINO_FNS(flag) \ 18662306a36Sopenharmony_cistatic inline int NInoTestSet##flag(ntfs_inode *ni) \ 18762306a36Sopenharmony_ci{ \ 18862306a36Sopenharmony_ci return test_and_set_bit(NI_##flag, &(ni)->state); \ 18962306a36Sopenharmony_ci} \ 19062306a36Sopenharmony_cistatic inline int NInoTestClear##flag(ntfs_inode *ni) \ 19162306a36Sopenharmony_ci{ \ 19262306a36Sopenharmony_ci return test_and_clear_bit(NI_##flag, &(ni)->state); \ 19362306a36Sopenharmony_ci} 19462306a36Sopenharmony_ci 19562306a36Sopenharmony_ci/* Emit the ntfs inode bitops functions. */ 19662306a36Sopenharmony_ciNINO_FNS(Dirty) 19762306a36Sopenharmony_ciTAS_NINO_FNS(Dirty) 19862306a36Sopenharmony_ciNINO_FNS(AttrList) 19962306a36Sopenharmony_ciNINO_FNS(AttrListNonResident) 20062306a36Sopenharmony_ciNINO_FNS(Attr) 20162306a36Sopenharmony_ciNINO_FNS(MstProtected) 20262306a36Sopenharmony_ciNINO_FNS(NonResident) 20362306a36Sopenharmony_ciNINO_FNS(IndexAllocPresent) 20462306a36Sopenharmony_ciNINO_FNS(Compressed) 20562306a36Sopenharmony_ciNINO_FNS(Encrypted) 20662306a36Sopenharmony_ciNINO_FNS(Sparse) 20762306a36Sopenharmony_ciNINO_FNS(SparseDisabled) 20862306a36Sopenharmony_ciNINO_FNS(TruncateFailed) 20962306a36Sopenharmony_ci 21062306a36Sopenharmony_ci/* 21162306a36Sopenharmony_ci * The full structure containing a ntfs_inode and a vfs struct inode. Used for 21262306a36Sopenharmony_ci * all real and fake inodes but not for extent inodes which lack the vfs struct 21362306a36Sopenharmony_ci * inode. 21462306a36Sopenharmony_ci */ 21562306a36Sopenharmony_citypedef struct { 21662306a36Sopenharmony_ci ntfs_inode ntfs_inode; 21762306a36Sopenharmony_ci struct inode vfs_inode; /* The vfs inode structure. */ 21862306a36Sopenharmony_ci} big_ntfs_inode; 21962306a36Sopenharmony_ci 22062306a36Sopenharmony_ci/** 22162306a36Sopenharmony_ci * NTFS_I - return the ntfs inode given a vfs inode 22262306a36Sopenharmony_ci * @inode: VFS inode 22362306a36Sopenharmony_ci * 22462306a36Sopenharmony_ci * NTFS_I() returns the ntfs inode associated with the VFS @inode. 22562306a36Sopenharmony_ci */ 22662306a36Sopenharmony_cistatic inline ntfs_inode *NTFS_I(struct inode *inode) 22762306a36Sopenharmony_ci{ 22862306a36Sopenharmony_ci return (ntfs_inode *)container_of(inode, big_ntfs_inode, vfs_inode); 22962306a36Sopenharmony_ci} 23062306a36Sopenharmony_ci 23162306a36Sopenharmony_cistatic inline struct inode *VFS_I(ntfs_inode *ni) 23262306a36Sopenharmony_ci{ 23362306a36Sopenharmony_ci return &((big_ntfs_inode *)ni)->vfs_inode; 23462306a36Sopenharmony_ci} 23562306a36Sopenharmony_ci 23662306a36Sopenharmony_ci/** 23762306a36Sopenharmony_ci * ntfs_attr - ntfs in memory attribute structure 23862306a36Sopenharmony_ci * @mft_no: mft record number of the base mft record of this attribute 23962306a36Sopenharmony_ci * @name: Unicode name of the attribute (NULL if unnamed) 24062306a36Sopenharmony_ci * @name_len: length of @name in Unicode characters (0 if unnamed) 24162306a36Sopenharmony_ci * @type: attribute type (see layout.h) 24262306a36Sopenharmony_ci * 24362306a36Sopenharmony_ci * This structure exists only to provide a small structure for the 24462306a36Sopenharmony_ci * ntfs_{attr_}iget()/ntfs_test_inode()/ntfs_init_locked_inode() mechanism. 24562306a36Sopenharmony_ci * 24662306a36Sopenharmony_ci * NOTE: Elements are ordered by size to make the structure as compact as 24762306a36Sopenharmony_ci * possible on all architectures. 24862306a36Sopenharmony_ci */ 24962306a36Sopenharmony_citypedef struct { 25062306a36Sopenharmony_ci unsigned long mft_no; 25162306a36Sopenharmony_ci ntfschar *name; 25262306a36Sopenharmony_ci u32 name_len; 25362306a36Sopenharmony_ci ATTR_TYPE type; 25462306a36Sopenharmony_ci} ntfs_attr; 25562306a36Sopenharmony_ci 25662306a36Sopenharmony_ciextern int ntfs_test_inode(struct inode *vi, void *data); 25762306a36Sopenharmony_ci 25862306a36Sopenharmony_ciextern struct inode *ntfs_iget(struct super_block *sb, unsigned long mft_no); 25962306a36Sopenharmony_ciextern struct inode *ntfs_attr_iget(struct inode *base_vi, ATTR_TYPE type, 26062306a36Sopenharmony_ci ntfschar *name, u32 name_len); 26162306a36Sopenharmony_ciextern struct inode *ntfs_index_iget(struct inode *base_vi, ntfschar *name, 26262306a36Sopenharmony_ci u32 name_len); 26362306a36Sopenharmony_ci 26462306a36Sopenharmony_ciextern struct inode *ntfs_alloc_big_inode(struct super_block *sb); 26562306a36Sopenharmony_ciextern void ntfs_free_big_inode(struct inode *inode); 26662306a36Sopenharmony_ciextern void ntfs_evict_big_inode(struct inode *vi); 26762306a36Sopenharmony_ci 26862306a36Sopenharmony_ciextern void __ntfs_init_inode(struct super_block *sb, ntfs_inode *ni); 26962306a36Sopenharmony_ci 27062306a36Sopenharmony_cistatic inline void ntfs_init_big_inode(struct inode *vi) 27162306a36Sopenharmony_ci{ 27262306a36Sopenharmony_ci ntfs_inode *ni = NTFS_I(vi); 27362306a36Sopenharmony_ci 27462306a36Sopenharmony_ci ntfs_debug("Entering."); 27562306a36Sopenharmony_ci __ntfs_init_inode(vi->i_sb, ni); 27662306a36Sopenharmony_ci ni->mft_no = vi->i_ino; 27762306a36Sopenharmony_ci} 27862306a36Sopenharmony_ci 27962306a36Sopenharmony_ciextern ntfs_inode *ntfs_new_extent_inode(struct super_block *sb, 28062306a36Sopenharmony_ci unsigned long mft_no); 28162306a36Sopenharmony_ciextern void ntfs_clear_extent_inode(ntfs_inode *ni); 28262306a36Sopenharmony_ci 28362306a36Sopenharmony_ciextern int ntfs_read_inode_mount(struct inode *vi); 28462306a36Sopenharmony_ci 28562306a36Sopenharmony_ciextern int ntfs_show_options(struct seq_file *sf, struct dentry *root); 28662306a36Sopenharmony_ci 28762306a36Sopenharmony_ci#ifdef NTFS_RW 28862306a36Sopenharmony_ci 28962306a36Sopenharmony_ciextern int ntfs_truncate(struct inode *vi); 29062306a36Sopenharmony_ciextern void ntfs_truncate_vfs(struct inode *vi); 29162306a36Sopenharmony_ci 29262306a36Sopenharmony_ciextern int ntfs_setattr(struct mnt_idmap *idmap, 29362306a36Sopenharmony_ci struct dentry *dentry, struct iattr *attr); 29462306a36Sopenharmony_ci 29562306a36Sopenharmony_ciextern int __ntfs_write_inode(struct inode *vi, int sync); 29662306a36Sopenharmony_ci 29762306a36Sopenharmony_cistatic inline void ntfs_commit_inode(struct inode *vi) 29862306a36Sopenharmony_ci{ 29962306a36Sopenharmony_ci if (!is_bad_inode(vi)) 30062306a36Sopenharmony_ci __ntfs_write_inode(vi, 1); 30162306a36Sopenharmony_ci return; 30262306a36Sopenharmony_ci} 30362306a36Sopenharmony_ci 30462306a36Sopenharmony_ci#else 30562306a36Sopenharmony_ci 30662306a36Sopenharmony_cistatic inline void ntfs_truncate_vfs(struct inode *vi) {} 30762306a36Sopenharmony_ci 30862306a36Sopenharmony_ci#endif /* NTFS_RW */ 30962306a36Sopenharmony_ci 31062306a36Sopenharmony_ci#endif /* _LINUX_NTFS_INODE_H */ 311