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