1/* 2 * ntfs_inode.h - Defines for inode structures for the NTFS kernel driver. 3 * 4 * Copyright (c) 2006-2011 Anton Altaparmakov. All Rights Reserved. 5 * Portions Copyright (c) 2006-2011 Apple Inc. All Rights Reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions are met: 9 * 10 * 1. Redistributions of source code must retain the above copyright notice, 11 * this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright notice, 13 * this list of conditions and the following disclaimer in the documentation 14 * and/or other materials provided with the distribution. 15 * 3. Neither the name of Apple Inc. ("Apple") nor the names of its 16 * contributors may be used to endorse or promote products derived from this 17 * software without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY 20 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY 23 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 26 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 * 30 * ALTERNATIVELY, provided that this notice and licensing terms are retained in 31 * full, this file may be redistributed and/or modified under the terms of the 32 * GNU General Public License (GPL) Version 2, in which case the provisions of 33 * that version of the GPL will apply to you instead of the license terms 34 * above. You can obtain a copy of the GPL Version 2 at 35 * http://developer.apple.com/opensource/licenses/gpl-2.txt. 36 */ 37 38#ifndef _OSX_NTFS_INODE_H 39#define _OSX_NTFS_INODE_H 40 41#include <sys/buf.h> 42#include <sys/errno.h> 43#include <sys/kernel_types.h> 44#include <sys/proc.h> 45#include <sys/queue.h> 46#include <sys/time.h> 47#include <sys/types.h> 48#include <sys/ucred.h> 49#include <sys/vnode.h> 50#include <sys/xattr.h> 51 52#include <libkern/OSTypes.h> 53 54#include <kern/debug.h> 55#include <kern/locks.h> 56 57/* Forward declarations. */ 58typedef struct _ntfs_inode ntfs_inode; 59typedef struct _ntfs_attr ntfs_attr; 60struct _ntfs_dirhint; 61 62/* Structures associated with ntfs inode caching. */ 63typedef LIST_HEAD(, _ntfs_inode) ntfs_inode_list_head; 64typedef LIST_ENTRY(_ntfs_inode) ntfs_inode_list_entry; 65 66#include "ntfs_layout.h" 67#include "ntfs_runlist.h" 68#include "ntfs_sfm.h" 69#include "ntfs_types.h" 70#include "ntfs_vnops.h" 71#include "ntfs_volume.h" 72 73/* The NTFS in-memory inode structure. */ 74struct _ntfs_inode { 75 ntfs_inode_list_entry hash; /* Hash bucket list this inode is in. */ 76 ntfs_volume *vol; /* Pointer to the ntfs volume of this inode. */ 77 vnode_t vn; /* Vnode attached to the ntfs inode or NULL if 78 this is an extent ntfs inode. */ 79 SInt32 nr_refs; /* This is the number of usecount references on 80 the vnode of this inode that are held by 81 ntfs driver internal entities. For extent 82 mft records, this is always zero. */ 83 SInt32 nr_opens; /* This is the number of VNOP_OPEN() calls that 84 have happened on the vnode of this inode 85 that have not had a matching VNOP_CLOSE() 86 call yet. Note this applies only to base 87 inodes and is incremented/decremented in the 88 base inode for attribute/raw inode 89 opens/closes, too. */ 90 lck_rw_t lock; /* Lock serializing changes to the inode such 91 as inode truncation and directory content 92 modification (both take the lock exclusive) 93 and calls like readdir and file read (these 94 take the lock shared). */ 95 u32 block_size; /* Size in bytes of a logical block in the 96 inode. For normal attributes this is the 97 sector size and for mst protected attributes 98 this is the size of an mst protected ntfs 99 record. */ 100 u8 block_size_shift; /* Log2 of the above. */ 101 lck_spin_t size_lock; /* Lock serializing access to inode sizes. */ 102 s64 allocated_size; /* Copy from the attribute record. */ 103 s64 data_size; /* Copy from the attribute record. */ 104 s64 initialized_size; /* Copy from the attribute record. */ 105 u32 flags; /* NTFS specific flags describing this inode. 106 See ntfs_inode_flags_shift below. */ 107 ino64_t mft_no; /* Number of the mft record / inode. */ 108 u16 seq_no; /* Sequence number of the inode. */ 109 unsigned link_count; /* Number of hard links to this inode. Note we 110 make this field an integer, i.e. at least 111 32-bit to allow us to temporarily overflow 112 16-bits in ntfs_vnop_rename(). */ 113 uid_t uid; /* Inode user owner. */ 114 gid_t gid; /* Inode group owner. */ 115 mode_t mode; /* Inode mode. */ 116 dev_t rdev; /* For block and character device special 117 inodes this is the device. */ 118 FILE_ATTR_FLAGS file_attributes; /* Cached file attributes from 119 the standard information 120 attribute. */ 121 struct timespec creation_time; /* Cache of fields found in */ 122 struct timespec last_data_change_time; /* the standard information */ 123 struct timespec last_mft_change_time; /* attribute but in OS X time */ 124 struct timespec last_access_time; /* format. */ 125 struct timespec backup_time; /* Cache of field in the 126 AFP_AfpInfo stream but in 127 OS X time format. */ 128 FINDER_INFO finder_info; /* Cached Finder info from the 129 AFP_AfpInfo stream. */ 130 /* 131 * If NInoAttr() is true, the below fields describe the attribute which 132 * this fake inode belongs to. The actual inode of this attribute is 133 * pointed to by base_ni and nr_extents is set to -1 to indicate that 134 * base_ni is valid (see below). For real inodes, we also set the type 135 * (AT_DATA for files and AT_INDEX_ALLOCATION for directories), with 136 * the name = NULL and name_len = 0 for files and name = I30 (ntfs 137 * driver wide constant) and name_len = 4 for directories. 138 */ 139 ATTR_TYPE type; /* Attribute type of this fake inode. */ 140 ntfschar *name; /* Attribute name of this fake inode. */ 141 u32 name_len; /* Attribute name length of this fake inode. */ 142 ntfs_runlist rl; /* If flags has the NI_NonResident bit set, 143 the runlist of the unnamed data attribute 144 (if a file) or of the index allocation 145 attribute (directory) or of the attribute 146 described by the fake inode (if NInoAttr()). 147 If rl.elements is 0, the runlist has not 148 been read in yet or has been unmapped. If 149 NI_NonResident is clear, the attribute is 150 resident (file and fake inode) or there is 151 no $I30 index allocation attribute 152 (small directory). In the latter case 153 rl.elements is always zero. */ 154 ntfs_runlist url; /* This runlist represents all uninitialized 155 regions such as holes or parts of holes that 156 have been instantiated but have not yet been 157 zeroed nor written to. Another significance 158 is the initialized size. When it is 159 incremented without zeroing the underlying 160 clusters these regions are entered in this 161 runlist. This runlist must be consulted on 162 reads so that zeroes are read from the 163 uninitialized regions and must be updated on 164 writes so that uninitialized regions are 165 removed from the runlist when they are 166 zeroed or written. Finally we have to go 167 through this runlist at sync time and have 168 to then zero out the uninitialized regions 169 and remove them from this runlist. The way 170 we implement this runlist is that all 171 uninitialized regions are entered as 172 duplicates of their real counterparts in the 173 actual runlist @rl whilst all initialized 174 regions are stored as holes. Thus the 175 fewer uninitialized regions an attribute has 176 the fewer elements will this runlist have. 177 And when there are no uninitialized elements 178 at all then this runlist is not in use and 179 its @url.elements field is set to zero thus 180 it consumes no extra memory allocation. 181 Storing things in this way means we do not 182 need to perform any lookups in the real 183 runlist whilst zeroing the uninitialized 184 regions. TODO: What happens if we have 185 uninitialized regions outside the 186 initialized size and then someone increments 187 the initialized size? We need to take care 188 that we don't get into a situation where 189 merging fragments of the real runlist and 190 fragments of the uninitialized runlist will 191 fail. */ 192 /* 193 * The following fields are only valid for real inodes and extent 194 * inodes. 195 */ 196 ntfs_inode *mft_ni; /* Pointer to the ntfs inode of $MFT. */ 197 buf_t m_buf; /* Buffer containing the mft record of the 198 inode. This should only be touched by the 199 ntfs_*mft_record_(un)map() functions. */ 200 MFT_RECORD *m; /* Address of the buffer data and thus address 201 of the mft record. This should only be 202 touched by the ntfs_*mft_record_(un)map() 203 functions. */ 204 /* 205 * Attribute list support (only for use by the attribute lookup 206 * functions). Setup during read_inode for all inodes with attribute 207 * lists. Only valid if NI_AttrList is set in flags, and attr_list_rl 208 * is further only valid if NI_AttrListNonResident is set. 209 */ 210 u32 attr_list_size; /* Length of attribute list value in bytes. */ 211 u32 attr_list_alloc; /* Number of bytes allocated for the attr_list 212 buffer. */ 213 u8 *attr_list; /* Attribute list value itself. */ 214 ntfs_runlist attr_list_rl; /* Run list for the attribute list value. */ 215 union { 216 struct { /* It is a directory, $MFT, or an index inode. */ 217 s64 last_set_bit; /* The last bit that is set in 218 the index $BITMAP. If not 219 known this is set to -1. */ 220 u32 vcn_size; /* Size of a vcn in this 221 index. */ 222 COLLATION_RULE collation_rule; /* The collation rule 223 for the index. */ 224 u8 vcn_size_shift; /* Log2 of the above. */ 225 u8 nr_dirhints; /* Number of directory hints 226 attached to this index 227 inode. */ 228 u16 dirhint_tag; /* The most recently created 229 directory hint tag. */ 230 TAILQ_HEAD(ntfs_dirhint_head, _ntfs_dirhint) 231 dirhint_list; /* List of directory 232 hints. */ 233 }; 234 struct { /* It is a compressed/sparse file/attribute inode. */ 235 s64 compressed_size; /* Copy of compressed_size from 236 $DATA. */ 237 u32 compression_block_size; /* Size of a compression 238 block (cb). */ 239 u8 compression_block_size_shift;/* Log2 of the size of 240 a cb. */ 241 u8 compression_block_clusters; /* Number of clusters 242 per cb. */ 243 }; 244 }; 245 lck_mtx_t extent_lock; /* Lock for accessing/modifying the below . */ 246 s32 nr_extents; /* For a base mft record, the number of attached extent 247 inodes (0 if none), for extent records and for fake 248 inodes describing an attribute this is -1 if the 249 base inode at @base_ni is valid and 0 otherwise. */ 250 u32 extent_alloc; /* Number of bytes allocated for the extent_nis 251 array. */ 252 lck_mtx_t attr_nis_lock; /* Lock for accessing/modifying the below. */ 253 s32 nr_attr_nis; /* For a base inode, the number of loaded 254 attribute inodes (0 if none). Ignored for 255 attribut inodes and fake inodes. */ 256 u32 attr_nis_alloc; /* Number of bytes allocated for the attr_nis 257 array. */ 258 union { /* This union is only used if nr_extents != 0. */ 259 struct { 260 ntfs_inode **extent_nis; /* For nr_extents > 0, array 261 of the ntfs inodes of the 262 extent mft records 263 belonging to this base 264 inode which have been 265 loaded. Allocated in 266 multiples of 4 elements. */ 267 ntfs_inode **attr_nis; /* For nr_attr_nis > 0, array 268 of the loaded attribute 269 inodes. Allocated in 270 multiples of 4 elements. */ 271 }; 272 struct { 273 ntfs_inode *base_ni; /* For nr_extents == -1, the 274 ntfs inode of the base mft 275 record. For fake inodes, the 276 real (base) inode to which 277 the attribute belongs. */ 278 lck_mtx_t *base_attr_nis_lock; /* Pointer to the base 279 inode 280 attr_nis_lock or 281 NULL. */ 282 }; 283 }; 284 ntfs_inode_list_entry inodes; /* List of ntfs inodes attached to the 285 ntfs volume. */ 286}; 287 288/* 289 * Defined bits for the flags field in the ntfs_inode structure. 290 * (f) = files only, (d) = directories only, (a) = attributes/fake inodes only 291 */ 292typedef enum { 293 NI_Locked, /* 1: Ntfs inode is locked. */ 294 NI_Alloc, /* 1: Ntfs inode is being allocated now. */ 295 NI_Deleted, /* 1: Ntfs inode has been deleted. */ 296 NI_Reclaim, /* 1: Ntfs inode is being reclaimed now. */ 297 NI_AttrList, /* 1: Mft record contains an attribute list. */ 298 NI_AttrListNonResident, /* 1: Attribute list is non-resident. Implies 299 NI_AttrList is set. */ 300 NI_Attr, /* 1: Fake inode for attribute i/o. 301 0: Real inode or extent inode. */ 302 NI_MstProtected, /* 1: Attribute is protected by MST fixups. 303 0: Attribute is not protected by fixups. */ 304 NI_NonResident, /* 1: Unnamed data attr is non-resident (f). 305 1: Attribute is non-resident (a). */ 306 NI_IndexAllocPresent = NI_NonResident, /* 1: $I30 index alloc attr is 307 present (d). */ 308 NI_Compressed, /* 1: Unnamed data attr is compressed (f). 309 1: Create compressed files by default (d). 310 1: Attribute is compressed (a). */ 311 NI_Encrypted, /* 1: Unnamed data attr is encrypted (f). 312 1: Create encrypted files by default (d). 313 1: Attribute is encrypted (a). */ 314 NI_Sparse, /* 1: Unnamed data attr is sparse (f). 315 1: Create sparse files by default (d). 316 1: Attribute is sparse (a). */ 317 NI_SparseDisabled, /* 1: May not create sparse regions. */ 318 NI_NotMrecPageOwner, /* 1: This inode does not own the mft record 319 page. 320 0: Thus inode does own the mft record 321 page. */ 322 NI_MrecNeedsDirtying, /* 1: Page containing the mft record needs to 323 be marked dirty. */ 324 NI_Raw, /* 1: Access the raw data of the inode rather 325 than decompressing or decrypting the 326 data for example. Note, that NInoRaw() 327 implies NInoAttr() as well. */ 328 NI_DirtyTimes, /* 1: Base ntfs inode contains updated times 329 that need to be written to the standard 330 information attribute and all directory 331 index entries pointing to the inode (f, 332 d). Note this does not include the 333 backup time (see below). */ 334 NI_DirtyFileAttributes, /* 1: Base ntfs inode contains updated file 335 attributes that need to be written to the 336 standard information attribute and all 337 directory index entries pointing to the 338 inode (f, d). */ 339 NI_DirtySizes, /* 1: Base ntfs inode contains updated sizes 340 that need to be written to all directory 341 index entries pointing to the inode (f). 342 Directories always have both sizes set to 343 zero in their index entries so this is 344 not relevant. */ 345 NI_DirtySetFileBits, /* 1: Base ntfs inode contains updated special 346 mode bits S_ISUID, S_ISGID, and/or 347 S_ISVTX that need to be written to the 348 SETFILEBITS EA (used by Interix POSIX 349 subsystem on Windows as installed by the 350 Windows Services For Unix, aka SFU) (f, 351 d). */ 352 NI_ValidBackupTime, /* 1: Base ntfs inode contains valid backup 353 time, i.e. the backup time has either 354 been loaded from the AFP_AfpInfo stream 355 or it has been set via VNOP_SETATTR() in 356 which case it will also be marked dirty, 357 i.e. the NI_DirtyBackupTime bit will also 358 be set (f, d) if it has not been synced 359 to the AFP_AfpInfo attribute yet. */ 360 NI_DirtyBackupTime, /* 1: Base ntfs inode contains updated 361 backup_time that needs to be written to 362 the AFP_AfpInfo stream (after creating it 363 if it does not exist already) (f, d). */ 364 NI_ValidFinderInfo, /* 1: Base ntfs inode contains valid Finder 365 info, i.e. the Finder info has either 366 been loaded from the AFP_AfpInfo stream 367 or it has been set via VNOP_SETXATTR() in 368 which case it will also be marked dirty, 369 i.e. the NI_DirtyFinderInfo bit will also 370 be set (f, d) if it has not been synced 371 to the AFP_AfpInfo attribute yet. */ 372 NI_DirtyFinderInfo, /* 1: Base ntfs inode contains updated Finder 373 info that needs to be writte to the 374 AFP_AfpInfo stream (after creating it 375 if it does not exist already) (f, d). */ 376} ntfs_inode_flags_shift; 377 378/* 379 * Macro to expand the NInoFoo(), NInoSetFoo(), and NInoClearFoo() functions. 380 * Note, these functions are atomic but do not necessarily provide any ordering 381 * guarantees. This should be fine as they are always used with a lock held 382 * and/or in places where the ordering does not matter. 383 */ 384#define DEFINE_NINO_BIT_OPS(flag) \ 385static inline u32 NIno##flag(ntfs_inode *ni) \ 386{ \ 387 return (ni->flags >> NI_##flag) & 1; \ 388} \ 389static inline void NInoSet##flag(ntfs_inode *ni) \ 390{ \ 391 (void)OSBitOrAtomic((u32)1 << NI_##flag, (UInt32*)&ni->flags); \ 392} \ 393static inline void NInoClear##flag(ntfs_inode *ni) \ 394{ \ 395 (void)OSBitAndAtomic(~((u32)1 << NI_##flag), (UInt32*)&ni->flags); \ 396} 397 398/* 399 * As above for NInoTestSetFoo() and NInoTestClearFoo(). 400 */ 401#define DEFINE_NINO_TEST_AND_SET_BIT_OPS(flag) \ 402static inline u32 NInoTestSet##flag(ntfs_inode *ni) \ 403{ \ 404 return ((u32)OSBitOrAtomic((u32)1 << NI_##flag, \ 405 (UInt32*)&ni->flags) >> NI_##flag) & 1; \ 406} \ 407static inline u32 NInoTestClear##flag(ntfs_inode *ni) \ 408{ \ 409 return ((u32)OSBitAndAtomic(~((u32)1 << NI_##flag), \ 410 (UInt32*)&ni->flags) >> NI_##flag) & 1; \ 411} 412 413/* Emit the ntfs inode bitops functions. */ 414DEFINE_NINO_BIT_OPS(Locked) 415DEFINE_NINO_BIT_OPS(Alloc) 416 417static inline void NInoClearAllocLocked(ntfs_inode *ni) 418{ 419 (void)OSBitAndAtomic(~(((u32)1 << NI_Locked) | ((u32)1 << NI_Alloc)), 420 (UInt32*)&ni->flags); 421} 422 423DEFINE_NINO_BIT_OPS(Deleted) 424DEFINE_NINO_BIT_OPS(Reclaim) 425DEFINE_NINO_BIT_OPS(AttrList) 426DEFINE_NINO_BIT_OPS(AttrListNonResident) 427DEFINE_NINO_BIT_OPS(Attr) 428DEFINE_NINO_BIT_OPS(MstProtected) 429DEFINE_NINO_BIT_OPS(NonResident) 430DEFINE_NINO_BIT_OPS(IndexAllocPresent) 431DEFINE_NINO_BIT_OPS(Compressed) 432DEFINE_NINO_BIT_OPS(Encrypted) 433DEFINE_NINO_BIT_OPS(Sparse) 434DEFINE_NINO_BIT_OPS(SparseDisabled) 435DEFINE_NINO_BIT_OPS(NotMrecPageOwner) 436DEFINE_NINO_TEST_AND_SET_BIT_OPS(NotMrecPageOwner) 437DEFINE_NINO_BIT_OPS(MrecNeedsDirtying) 438DEFINE_NINO_TEST_AND_SET_BIT_OPS(MrecNeedsDirtying) 439DEFINE_NINO_BIT_OPS(Raw) 440DEFINE_NINO_BIT_OPS(DirtyTimes) 441DEFINE_NINO_TEST_AND_SET_BIT_OPS(DirtyTimes) 442DEFINE_NINO_BIT_OPS(DirtyFileAttributes) 443DEFINE_NINO_TEST_AND_SET_BIT_OPS(DirtyFileAttributes) 444DEFINE_NINO_BIT_OPS(DirtySizes) 445DEFINE_NINO_TEST_AND_SET_BIT_OPS(DirtySizes) 446DEFINE_NINO_BIT_OPS(DirtySetFileBits) 447DEFINE_NINO_TEST_AND_SET_BIT_OPS(DirtySetFileBits) 448DEFINE_NINO_BIT_OPS(ValidBackupTime) 449DEFINE_NINO_BIT_OPS(DirtyBackupTime) 450DEFINE_NINO_TEST_AND_SET_BIT_OPS(DirtyBackupTime) 451DEFINE_NINO_BIT_OPS(ValidFinderInfo) 452DEFINE_NINO_BIT_OPS(DirtyFinderInfo) 453DEFINE_NINO_TEST_AND_SET_BIT_OPS(DirtyFinderInfo) 454 455/* Function to bulk check all the Dirty* flags at once. */ 456static inline u32 NInoDirty(ntfs_inode *ni) 457{ 458 return (ni->flags & (((u32)1 << NI_DirtyTimes) | 459 ((u32)1 << NI_DirtyFileAttributes) | 460 ((u32)1 << NI_DirtySizes) | 461 ((u32)1 << NI_DirtySetFileBits) | 462 ((u32)1 << NI_DirtyBackupTime) | 463 ((u32)1 << NI_DirtyFinderInfo))) ? 1 : 0; 464} 465 466/** 467 * NTFS_I - return the ntfs inode given a vfs vnode 468 * @vn: VFS vnode 469 * 470 * NTFS_I() returns the ntfs inode associated with the VFS vnode @vn. 471 */ 472static inline ntfs_inode *NTFS_I(vnode_t vn) 473{ 474 return vnode_fsnode(vn); 475} 476 477/** 478 * ntfs_attr - ntfs in memory attribute structure 479 * @mft_no: mft record number of the base mft record of this attribute 480 * @name: Unicode name of the attribute (NULL if unnamed) 481 * @name_len: length of @name in Unicode characters (0 if unnamed) 482 * @type: attribute type (see ntfs_layout.h) 483 * @raw: whether this is the raw inode (TRUE) or not (FALSE) 484 * 485 * This structure exists only to provide a small structure for the ntfs_inode 486 * and ntfs_inode_hash related functions. 487 * 488 * NOTE: Elements are ordered by size to make the structure as compact as 489 * possible on all architectures. 490 */ 491struct _ntfs_attr { 492 ino64_t mft_no; 493 ntfschar *name; 494 u32 name_len; 495 ATTR_TYPE type; 496 BOOL raw; 497}; 498 499__private_extern__ BOOL ntfs_inode_test(ntfs_inode *ni, const ntfs_attr *na); 500 501__private_extern__ errno_t ntfs_inode_init(ntfs_volume *vol, ntfs_inode *ni, 502 const ntfs_attr *na); 503 504/** 505 * ntfs_inode_wait - wait for an ntfs inode 506 * @ni: ntfs inode to wait on 507 * @lock: drop this lock whilst waiting 508 */ 509#define ntfs_inode_wait(ni, lock) \ 510 do { \ 511 (void)msleep(ni, lock, PDROP | PINOD, __FUNCTION__, 0); \ 512 } while (0) 513 514/** 515 * ntfs_inode_wait_locked - wait for an ntfs inode to be unlocked 516 * @ni: ntfs inode to wait on 517 * @lock: drop this lock whilst waiting 518 */ 519#define ntfs_inode_wait_locked(ni, lock) \ 520 do { \ 521 if (NInoLocked(ni)) { \ 522 lck_mtx_t *lck = lock; \ 523 do { \ 524 /* Drops lock. */ \ 525 ntfs_inode_wait(ni, lck); \ 526 /* Lock is dropped now. */ \ 527 lck = NULL; \ 528 } while (NInoLocked(ni)); \ 529 } else \ 530 lck_mtx_unlock(lock); \ 531 } while (0) 532 533/** 534 * ntfs_inode_wakeup - wakeup all processes waiting on an ntfs inode 535 * @ni: ntfs inode to wake up 536 */ 537static inline void ntfs_inode_wakeup(ntfs_inode *ni) 538{ 539 wakeup(ni); 540} 541 542/** 543 * ntfs_inode_unlock_alloc - unlock a newly allocated inode 544 * @ni: ntfs inode to unlock 545 * 546 * When a newly allocated inode is fully initialized, we need to clear the 547 * NI_Alloc and NI_Locked flag and wakeup any waiters on the inode. 548 */ 549static inline void ntfs_inode_unlock_alloc(ntfs_inode *ni) 550{ 551 NInoClearAllocLocked(ni); 552 ntfs_inode_wakeup(ni); 553} 554 555#define ntfs_inode_add_vnode(ni, is_system, parent_vn, cn) \ 556 ntfs_inode_add_vnode_attr(ni, is_system, parent_vn, cn, FALSE/*isstream*/) 557__private_extern__ errno_t ntfs_inode_add_vnode_attr(ntfs_inode *ni, 558 const BOOL is_system, vnode_t parent_vn, 559 struct componentname *cn, BOOL isstream); 560 561__private_extern__ errno_t ntfs_inode_get(ntfs_volume *vol, ino64_t mft_no, 562 const BOOL is_system, const lck_rw_type_t lock, 563 ntfs_inode **nni, vnode_t parent_vn, struct componentname *cn); 564 565__private_extern__ errno_t ntfs_attr_inode_lookup(ntfs_inode *base_ni, 566 ATTR_TYPE type, ntfschar *name, u32 name_len, const BOOL raw, 567 ntfs_inode **nni); 568 569__private_extern__ errno_t ntfs_attr_inode_get_or_create(ntfs_inode *base_ni, 570 ATTR_TYPE type, ntfschar *name, u32 name_len, 571 const BOOL is_system, const BOOL raw, const int options, 572 const lck_rw_type_t lock, ntfs_inode **nni); 573 574/** 575 * ntfs_attr_inode_get - obtain an ntfs inode corresponding to an attribute 576 * @base_ni: ntfs base inode containing the attribute 577 * @type: attribute type 578 * @name: Unicode name of the attribute (NULL if unnamed) 579 * @name_len: length of @name in Unicode characters (0 if unnamed) 580 * @is_system: true if the inode is a system inode and false otherwise 581 * @lock: locking options (see below) 582 * @nni: destination pointer for the obtained attribute ntfs inode 583 * 584 * Obtain the ntfs inode corresponding to the attribute specified by @type, 585 * @name, and @name_len, which is present in the base mft record specified by 586 * the ntfs inode @base_ni. If @is_system is true the created vnode is marked 587 * as a system vnode (via the VSYSTEM flag). 588 * 589 * If @lock is LCK_RW_TYPE_SHARED the attribute inode will be returned locked 590 * for reading (@nni->lock) and if it is LCK_RW_TYPE_EXCLUSIVE the attribute 591 * inode will be returned locked for writing (@nni->lock). As a special case 592 * if @lock is 0 it means the inode to be returned is already locked so do not 593 * lock it. This requires that the inode is already present in the inode 594 * cache. If it is not it cannot already be locked and thus you will get a 595 * panic(). 596 * 597 * If the attribute inode is in the cache, it is returned with an iocount 598 * reference on the attached vnode. 599 * 600 * If the inode is not in the cache, a new ntfs inode is allocated and 601 * initialized, ntfs_attr_inode_read_or_create() is called to read it in/create 602 * it and fill in the remainder of the ntfs inode structure before finally a 603 * new vnode is created and attached to the new ntfs inode. The inode is then 604 * returned with an iocount reference taken on its vnode. 605 * 606 * Note, for index allocation attributes, you need to use ntfs_index_inode_get() 607 * instead of ntfs_attr_inode_get() as working with indices is a lot more 608 * complex. 609 * 610 * Return 0 on success and errno on error. 611 * 612 * TODO: For now we do not store a name for attribute inodes. 613 */ 614static inline errno_t ntfs_attr_inode_get(ntfs_inode *base_ni, ATTR_TYPE type, 615 ntfschar *name, u32 name_len, const BOOL is_system, 616 const lck_rw_type_t lock, ntfs_inode **nni) 617{ 618 return ntfs_attr_inode_get_or_create(base_ni, type, name, name_len, 619 is_system, FALSE, XATTR_REPLACE, lock, nni); 620} 621 622/** 623 * ntfs_raw_inode_get - obtain the raw ntfs inode corresponding to an attribute 624 * @ni: non-raw ntfs inode containing the attribute 625 * @lock: locking options (see below) 626 * @nni: destination pointer for the obtained attribute ntfs inode 627 * 628 * Obtain the raw ntfs inode corresponding to the non-raw inode @ni. 629 * 630 * If @lock is LCK_RW_TYPE_SHARED the raw inode will be returned locked for 631 * reading (@nni->lock) and if it is LCK_RW_TYPE_EXCLUSIVE the raw inode will 632 * be returned locked for writing (@nni->lock). As a special case if @lock is 633 * 0 it means the inode to be returned is already locked so do not lock it. 634 * This requires that the inode is already present in the inode cache. If it 635 * is not it cannot already be locked and thus you will get a panic(). 636 * 637 * If the raw inode is in the cache, it is returned with an iocount reference 638 * on the attached vnode. 639 * 640 * If the raw inode is not in the cache, a new ntfs inode is allocated and 641 * initialized, ntfs_attr_inode_read_or_create() is called to read it in/create 642 * it and fill in the remainder of the ntfs inode structure before finally a 643 * new vnode is created and attached to the new ntfs inode. The inode is then 644 * returned with an iocount reference taken on its vnode. 645 * 646 * Return 0 on success and errno on error. 647 * 648 * Locking: The non-raw ntfs inode @ni must be locked (@ni->lock). 649 * 650 * TODO: For now we do not store a name for attribute inodes. 651 */ 652static inline errno_t ntfs_raw_inode_get(ntfs_inode *ni, 653 const lck_rw_type_t lock, ntfs_inode **nni) 654{ 655 if (NInoRaw(ni)) 656 panic("%s(): Function called for raw inode.\n", __FUNCTION__); 657 return ntfs_attr_inode_get_or_create(ni, ni->type, ni->name, 658 ni->name_len, FALSE, TRUE, XATTR_REPLACE, lock, nni); 659} 660 661__private_extern__ errno_t ntfs_index_inode_get(ntfs_inode *base_ni, 662 ntfschar *name, u32 name_len, const BOOL is_system, 663 ntfs_inode **nni); 664 665__private_extern__ errno_t ntfs_extent_inode_get(ntfs_inode *base_ni, 666 MFT_REF mref, ntfs_inode **ext_ni); 667 668__private_extern__ void ntfs_inode_afpinfo_cache(ntfs_inode *ni, AFPINFO *afp, 669 const unsigned afp_size); 670 671__private_extern__ errno_t ntfs_inode_afpinfo_read(ntfs_inode *ni); 672 673__private_extern__ errno_t ntfs_inode_afpinfo_write(ntfs_inode *ni); 674 675__private_extern__ errno_t ntfs_inode_inactive(ntfs_inode *ni); 676 677__private_extern__ errno_t ntfs_inode_reclaim(ntfs_inode *ni); 678 679__private_extern__ errno_t ntfs_inode_sync(ntfs_inode *ni, const int sync, 680 const BOOL skip_mft_record_sync); 681 682__private_extern__ errno_t ntfs_inode_get_name_and_parent_mref(ntfs_inode *ni, 683 BOOL have_parent, MFT_REF *mref, const char *name); 684 685__private_extern__ errno_t ntfs_inode_is_parent(ntfs_inode *parent_ni, 686 ntfs_inode *child_ni, BOOL *is_parent, ntfs_inode *forbid_ni); 687 688#endif /* !_OSX_NTFS_INODE_H */ 689