1 | /* |
---|
2 | * Copyright (C) 2011-2012 Paulo Alcantara <pcacjr@gmail.com> |
---|
3 | * |
---|
4 | * This program is free software; you can redistribute it and/or modify |
---|
5 | * it under the terms of the GNU General Public License as published by |
---|
6 | * the Free Software Foundation; either version 2 of the License, or |
---|
7 | * (at your option) any later version. |
---|
8 | * |
---|
9 | * This program is distributed in the hope that it will be useful, |
---|
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
---|
12 | * GNU General Public License for more details. |
---|
13 | * |
---|
14 | * You should have received a copy of the GNU General Public License |
---|
15 | * along with this program; if not, write to the |
---|
16 | * Free Software Foundation, Inc., |
---|
17 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
---|
18 | */ |
---|
19 | |
---|
20 | #include "runlist.h" |
---|
21 | |
---|
22 | #ifndef _NTFS_H_ |
---|
23 | #define _NTFS_H_ |
---|
24 | |
---|
25 | struct ntfs_bpb { |
---|
26 | uint8_t jmp_boot[3]; |
---|
27 | char oem_name[8]; |
---|
28 | uint16_t sector_size; |
---|
29 | uint8_t sec_per_clust; |
---|
30 | uint16_t res_sectors; |
---|
31 | uint8_t zero_0[3]; |
---|
32 | uint16_t zero_1; |
---|
33 | uint8_t media; |
---|
34 | uint16_t zero_2; |
---|
35 | uint16_t unused_0; |
---|
36 | uint16_t unused_1; |
---|
37 | uint32_t unused_2; |
---|
38 | uint32_t zero_3; |
---|
39 | uint32_t unused_3; |
---|
40 | uint64_t total_sectors; |
---|
41 | uint64_t mft_lclust; |
---|
42 | uint64_t mft_mirr_lclust; |
---|
43 | int8_t clust_per_mft_record; |
---|
44 | uint8_t unused_4[3]; |
---|
45 | uint8_t clust_per_idx_record; |
---|
46 | uint8_t unused_5[3]; |
---|
47 | uint64_t vol_serial; |
---|
48 | uint32_t unused_6; |
---|
49 | |
---|
50 | uint8_t pad[428]; /* padding to a sector boundary (512 bytes) */ |
---|
51 | } __attribute__((__packed__)); |
---|
52 | |
---|
53 | /* Function type for an NTFS-version-dependent MFT record lookup */ |
---|
54 | struct ntfs_mft_record; |
---|
55 | typedef struct ntfs_mft_record *f_mft_record_lookup(struct fs_info *, |
---|
56 | uint32_t, block_t *); |
---|
57 | |
---|
58 | struct ntfs_sb_info { |
---|
59 | block_t mft_blk; /* The first MFT record block */ |
---|
60 | uint64_t mft_lcn; /* LCN of the first MFT record */ |
---|
61 | unsigned mft_size; /* The MFT size in sectors */ |
---|
62 | uint64_t mft_record_size; /* MFT record size in bytes */ |
---|
63 | |
---|
64 | uint8_t clust_per_idx_record; /* Clusters per Index Record */ |
---|
65 | |
---|
66 | unsigned long long clusters; /* Total number of clusters */ |
---|
67 | |
---|
68 | unsigned clust_shift; /* Based on sectors */ |
---|
69 | unsigned clust_byte_shift; /* Based on bytes */ |
---|
70 | unsigned clust_mask; |
---|
71 | unsigned clust_size; |
---|
72 | |
---|
73 | uint8_t major_ver; /* Major version from $Volume */ |
---|
74 | uint8_t minor_ver; /* Minor version from $Volume */ |
---|
75 | |
---|
76 | /* NTFS-version-dependent MFT record lookup function to use */ |
---|
77 | f_mft_record_lookup *mft_record_lookup; |
---|
78 | } __attribute__((__packed__)); |
---|
79 | |
---|
80 | /* The NTFS in-memory inode structure */ |
---|
81 | struct ntfs_inode { |
---|
82 | int64_t initialized_size; |
---|
83 | int64_t allocated_size; |
---|
84 | unsigned long mft_no; /* Number of the mft record / inode */ |
---|
85 | uint16_t seq_no; /* Sequence number of the mft record */ |
---|
86 | uint32_t type; /* Attribute type of this inode */ |
---|
87 | uint8_t non_resident; |
---|
88 | union { /* Non-resident $DATA attribute */ |
---|
89 | struct { /* Used only if non_resident flags isn't set */ |
---|
90 | uint32_t offset; /* Data offset */ |
---|
91 | } resident; |
---|
92 | struct { /* Used only if non_resident is set */ |
---|
93 | struct runlist *rlist; |
---|
94 | } non_resident; |
---|
95 | } data; |
---|
96 | uint32_t start_cluster; /* Starting cluster address */ |
---|
97 | sector_t start; /* Starting sector */ |
---|
98 | sector_t offset; /* Current sector offset */ |
---|
99 | sector_t here; /* Sector corresponding to offset */ |
---|
100 | }; |
---|
101 | |
---|
102 | /* This is structure is used to keep a state for ntfs_readdir() callers. |
---|
103 | * As NTFS stores directory entries in a complex way, this is structure |
---|
104 | * ends up saving a state required to find out where we must start from |
---|
105 | * for the next ntfs_readdir() call. |
---|
106 | */ |
---|
107 | struct ntfs_readdir_state { |
---|
108 | unsigned long mft_no; /* MFT record number */ |
---|
109 | bool in_idx_root; /* It's true if we're still in the INDEX root */ |
---|
110 | uint32_t idx_blks_count; /* Number of read INDX blocks */ |
---|
111 | uint32_t entries_count; /* Number of read INDEX entries */ |
---|
112 | int64_t last_vcn; /* Last VCN of the INDX block */ |
---|
113 | }; |
---|
114 | |
---|
115 | enum { |
---|
116 | MAP_UNSPEC, |
---|
117 | MAP_START = 1 << 0, |
---|
118 | MAP_END = 1 << 1, |
---|
119 | MAP_ALLOCATED = 1 << 2, |
---|
120 | MAP_UNALLOCATED = 1 << 3, |
---|
121 | MAP_MASK = 0x0000000F, |
---|
122 | }; |
---|
123 | |
---|
124 | struct mapping_chunk { |
---|
125 | uint64_t vcn; |
---|
126 | int64_t lcn; |
---|
127 | uint64_t len; |
---|
128 | uint32_t flags; |
---|
129 | }; |
---|
130 | |
---|
131 | /* System defined attributes (32-bit) |
---|
132 | * Each attribute type has a corresponding attribute name (in Unicode) |
---|
133 | */ |
---|
134 | enum { |
---|
135 | NTFS_AT_UNUSED = 0x00, |
---|
136 | NTFS_AT_STANDARD_INFORMATION = 0x10, |
---|
137 | NTFS_AT_ATTR_LIST = 0x20, |
---|
138 | NTFS_AT_FILENAME = 0x30, |
---|
139 | NTFS_AT_OBJ_ID = 0x40, |
---|
140 | NTFS_AT_SECURITY_DESCP = 0x50, |
---|
141 | NTFS_AT_VOL_NAME = 0x60, |
---|
142 | NTFS_AT_VOL_INFO = 0x70, |
---|
143 | NTFS_AT_DATA = 0x80, |
---|
144 | NTFS_AT_INDEX_ROOT = 0x90, |
---|
145 | NTFS_AT_INDEX_ALLOCATION = 0xA0, |
---|
146 | NTFS_AT_BITMAP = 0xB0, |
---|
147 | NTFS_AT_REPARSE_POINT = 0xC0, |
---|
148 | NTFS_AT_EA_INFO = 0xD0, |
---|
149 | NTFS_AT_EA = 0xE0, |
---|
150 | NTFS_AT_PROPERTY_SET = 0xF0, |
---|
151 | NTFS_AT_LOGGED_UTIL_STREAM = 0x100, |
---|
152 | NTFS_AT_FIRST_USER_DEFINED_ATTR = 0x1000, |
---|
153 | NTFS_AT_END = 0xFFFFFFFF, |
---|
154 | }; |
---|
155 | |
---|
156 | /* NTFS File Permissions (also called attributes in DOS terminology) */ |
---|
157 | enum { |
---|
158 | NTFS_FILE_ATTR_READONLY = 0x00000001, |
---|
159 | NTFS_FILE_ATTR_HIDDEN = 0x00000002, |
---|
160 | NTFS_FILE_ATTR_SYSTEM = 0x00000004, |
---|
161 | NTFS_FILE_ATTR_DIRECTORY = 0x00000010, |
---|
162 | NTFS_FILE_ATTR_ARCHIVE = 0x00000020, |
---|
163 | NTFS_FILE_ATTR_DEVICE = 0x00000040, |
---|
164 | NTFS_FILE_ATTR_NORMAL = 0x00000080, |
---|
165 | NTFS_FILE_ATTR_TEMPORARY = 0x00000100, |
---|
166 | NTFS_FILE_ATTR_SPARSE_FILE = 0x00000200, |
---|
167 | NTFS_FILE_ATTR_REPARSE_POINT = 0x00000400, |
---|
168 | NTFS_FILE_ATTR_COMPRESSED = 0x00000800, |
---|
169 | NTFS_FILE_ATTR_OFFLINE = 0x00001000, |
---|
170 | NTFS_FILE_ATTR_NOT_CONTENT_INDEXED = 0x00002000, |
---|
171 | NTFS_FILE_ATTR_ENCRYPTED = 0x00004000, |
---|
172 | NTFS_FILE_ATTR_VALID_FLAGS = 0x00007FB7, |
---|
173 | NTFS_FILE_ATTR_VALID_SET_FLAGS = 0x000031A7, |
---|
174 | NTFS_FILE_ATTR_DUP_FILE_NAME_INDEX_PRESENT = 0x10000000, |
---|
175 | NTFS_FILE_ATTR_DUP_VIEW_INDEX_PRESENT = 0x20000000, |
---|
176 | }; |
---|
177 | |
---|
178 | /* |
---|
179 | * Magic identifiers present at the beginning of all ntfs record containing |
---|
180 | * records (like mft records for example). |
---|
181 | */ |
---|
182 | enum { |
---|
183 | /* Found in $MFT/$DATA */ |
---|
184 | NTFS_MAGIC_FILE = 0x454C4946, /* MFT entry */ |
---|
185 | NTFS_MAGIC_INDX = 0x58444E49, /* Index buffer */ |
---|
186 | NTFS_MAGIC_HOLE = 0x454C4F48, |
---|
187 | |
---|
188 | /* Found in $LogFile/$DATA */ |
---|
189 | NTFS_MAGIC_RSTR = 0x52545352, |
---|
190 | NTFS_MAGIC_RCRD = 0x44524352, |
---|
191 | /* Found in $LogFile/$DATA (May be found in $MFT/$DATA, also ?) */ |
---|
192 | NTFS_MAGIC_CHKDSK = 0x444B4843, |
---|
193 | /* Found in all ntfs record containing records. */ |
---|
194 | NTFS_MAGIC_BAAD = 0x44414142, |
---|
195 | NTFS_MAGIC_EMPTY = 0xFFFFFFFF, /* Record is empty */ |
---|
196 | }; |
---|
197 | |
---|
198 | struct ntfs_record { |
---|
199 | uint32_t magic; |
---|
200 | uint16_t usa_ofs; |
---|
201 | uint16_t usa_count; |
---|
202 | } __attribute__((__packed__)) NTFS_RECORD; |
---|
203 | |
---|
204 | /* The $MFT metadata file types */ |
---|
205 | enum ntfs_system_file { |
---|
206 | FILE_MFT = 0, |
---|
207 | FILE_MFTMirr = 1, |
---|
208 | FILE_LogFile = 2, |
---|
209 | FILE_Volume = 3, |
---|
210 | FILE_AttrDef = 4, |
---|
211 | FILE_root = 5, |
---|
212 | FILE_Bitmap = 6, |
---|
213 | FILE_Boot = 7, |
---|
214 | FILE_BadClus = 8, |
---|
215 | FILE_Secure = 9, |
---|
216 | FILE_UpCase = 10, |
---|
217 | FILE_Extend = 11, |
---|
218 | FILE_reserved12 = 12, |
---|
219 | FILE_reserved13 = 13, |
---|
220 | FILE_reserved14 = 14, |
---|
221 | FILE_reserved15 = 15, |
---|
222 | FILE_reserved16 = 16, |
---|
223 | }; |
---|
224 | |
---|
225 | enum { |
---|
226 | MFT_RECORD_IN_USE = 0x0001, |
---|
227 | MFT_RECORD_IS_DIRECTORY = 0x0002, |
---|
228 | } __attribute__((__packed__)); |
---|
229 | |
---|
230 | struct ntfs_mft_record { |
---|
231 | uint32_t magic; |
---|
232 | uint16_t usa_ofs; |
---|
233 | uint16_t usa_count; |
---|
234 | uint64_t lsn; |
---|
235 | uint16_t seq_no; |
---|
236 | uint16_t link_count; |
---|
237 | uint16_t attrs_offset; |
---|
238 | uint16_t flags; /* MFT record flags */ |
---|
239 | uint32_t bytes_in_use; |
---|
240 | uint32_t bytes_allocated; |
---|
241 | uint64_t base_mft_record; |
---|
242 | uint16_t next_attr_instance; |
---|
243 | uint16_t reserved; |
---|
244 | uint32_t mft_record_no; |
---|
245 | } __attribute__((__packed__)); /* 48 bytes */ |
---|
246 | |
---|
247 | /* This is the version without the NTFS 3.1+ specific fields */ |
---|
248 | struct ntfs_mft_record_old { |
---|
249 | uint32_t magic; |
---|
250 | uint16_t usa_ofs; |
---|
251 | uint16_t usa_count; |
---|
252 | uint64_t lsn; |
---|
253 | uint16_t seq_no; |
---|
254 | uint16_t link_count; |
---|
255 | uint16_t attrs_offset; |
---|
256 | uint16_t flags; /* MFT record flags */ |
---|
257 | uint32_t bytes_in_use; |
---|
258 | uint32_t bytes_allocated; |
---|
259 | uint64_t base_mft_record; |
---|
260 | uint16_t next_attr_instance; |
---|
261 | } __attribute__((__packed__)); /* 42 bytes */ |
---|
262 | |
---|
263 | enum { |
---|
264 | ATTR_DEF_INDEXABLE = 0x02, |
---|
265 | ATTR_DEF_MULTIPLE = 0x04, |
---|
266 | ATTR_DEF_NOT_ZERO = 0x08, |
---|
267 | ATTR_DEF_INDEXED_UNIQUE = 0x10, |
---|
268 | ATTR_DEF_NAMED_UNIQUE = 0x20, |
---|
269 | ATTR_DEF_RESIDENT = 0x40, |
---|
270 | ATTR_DEF_ALWAYS_LOG = 0x80, |
---|
271 | }; |
---|
272 | |
---|
273 | struct ntfs_attr_record { |
---|
274 | uint32_t type; /* Attr. type code */ |
---|
275 | uint32_t len; |
---|
276 | uint8_t non_resident; |
---|
277 | uint8_t name_len; |
---|
278 | uint16_t name_offset; |
---|
279 | uint16_t flags; /* Attr. flags */ |
---|
280 | uint16_t instance; |
---|
281 | union { |
---|
282 | struct { /* Resident attribute */ |
---|
283 | uint32_t value_len; |
---|
284 | uint16_t value_offset; |
---|
285 | uint8_t flags; /* Flags of resident attributes */ |
---|
286 | int8_t reserved; |
---|
287 | } __attribute__((__packed__)) resident; |
---|
288 | struct { /* Non-resident attributes */ |
---|
289 | uint64_t lowest_vcn; |
---|
290 | uint64_t highest_vcn; |
---|
291 | uint16_t mapping_pairs_offset; |
---|
292 | uint8_t compression_unit; |
---|
293 | uint8_t reserved[5]; |
---|
294 | int64_t allocated_size; |
---|
295 | int64_t data_size; /* Byte size of the attribute value. |
---|
296 | * Note: it can be larger than |
---|
297 | * allocated_size if attribute value is |
---|
298 | * compressed or sparse. |
---|
299 | */ |
---|
300 | int64_t initialized_size; |
---|
301 | int64_t compressed_size; |
---|
302 | } __attribute__((__packed__)) non_resident; |
---|
303 | } __attribute__((__packed__)) data; |
---|
304 | } __attribute__((__packed__)); |
---|
305 | |
---|
306 | /* Attribute: Attribute List (0x20) |
---|
307 | * Note: it can be either resident or non-resident |
---|
308 | */ |
---|
309 | struct ntfs_attr_list_entry { |
---|
310 | uint32_t type; |
---|
311 | uint16_t length; |
---|
312 | uint8_t name_length; |
---|
313 | uint8_t name_offset; |
---|
314 | uint64_t lowest_vcn; |
---|
315 | uint64_t mft_ref; |
---|
316 | uint16_t instance; |
---|
317 | uint16_t name[0]; |
---|
318 | } __attribute__((__packed__)); |
---|
319 | |
---|
320 | #define NTFS_MAX_FILE_NAME_LEN 255 |
---|
321 | |
---|
322 | /* Possible namespaces for filenames in ntfs (8-bit) */ |
---|
323 | enum { |
---|
324 | FILE_NAME_POSIX = 0x00, |
---|
325 | FILE_NAME_WIN32 = 0x01, |
---|
326 | FILE_NAME_DOS = 0x02, |
---|
327 | FILE_NAME_WIN32_AND_DOS = 0x03, |
---|
328 | } __attribute__((__packed__)); |
---|
329 | |
---|
330 | /* Attribute: Filename (0x30) |
---|
331 | * Note: always resident |
---|
332 | */ |
---|
333 | struct ntfs_filename_attr { |
---|
334 | uint64_t parent_directory; |
---|
335 | int64_t ctime; |
---|
336 | int64_t atime; |
---|
337 | int64_t mtime; |
---|
338 | int64_t rtime; |
---|
339 | uint64_t allocated_size; |
---|
340 | uint64_t data_size; |
---|
341 | uint32_t file_attrs; |
---|
342 | union { |
---|
343 | struct { |
---|
344 | uint16_t packed_ea_size; |
---|
345 | uint16_t reserved; /* reserved for alignment */ |
---|
346 | } __attribute__((__packed__)) ea; |
---|
347 | struct { |
---|
348 | uint32_t reparse_point_tag; |
---|
349 | } __attribute__((__packed__)) rp; |
---|
350 | } __attribute__((__packed__)) type; |
---|
351 | uint8_t file_name_len; |
---|
352 | uint8_t file_name_type; |
---|
353 | uint16_t file_name[0]; /* File name in Unicode */ |
---|
354 | } __attribute__((__packed__)); |
---|
355 | |
---|
356 | /* Attribute: Volume Name (0x60) |
---|
357 | * Note: always resident |
---|
358 | * Note: Present only in FILE_volume |
---|
359 | */ |
---|
360 | struct ntfs_vol_name { |
---|
361 | uint16_t name[0]; /* The name of the volume in Unicode */ |
---|
362 | } __attribute__((__packed__)); |
---|
363 | |
---|
364 | /* Attribute: Volume Information (0x70) |
---|
365 | * Note: always resident |
---|
366 | * Note: present only in FILE_Volume |
---|
367 | */ |
---|
368 | struct ntfs_vol_info { |
---|
369 | uint64_t reserved; |
---|
370 | uint8_t major_ver; |
---|
371 | uint8_t minor_ver; |
---|
372 | uint16_t flags; /* Volume flags */ |
---|
373 | } __attribute__((__packed__)); |
---|
374 | |
---|
375 | /* Attribute: Data attribute (0x80) |
---|
376 | * Note: can be either resident or non-resident |
---|
377 | */ |
---|
378 | struct ntfs_data_attr { |
---|
379 | uint8_t data[0]; |
---|
380 | } __attribute__((__packed__)); |
---|
381 | |
---|
382 | /* Index header flags (8-bit) */ |
---|
383 | enum { |
---|
384 | SMALL_INDEX = 0, |
---|
385 | LARGE_INDEX = 1, |
---|
386 | LEAF_NODE = 0, |
---|
387 | INDEX_NODE = 1, |
---|
388 | NODE_MASK = 1, |
---|
389 | } __attribute__((__packed__)); |
---|
390 | |
---|
391 | /* Header for the indexes, describing the INDEX_ENTRY records, which |
---|
392 | * follow the struct ntfs_idx_header. |
---|
393 | */ |
---|
394 | struct ntfs_idx_header { |
---|
395 | uint32_t entries_offset; |
---|
396 | uint32_t index_len; |
---|
397 | uint32_t allocated_size; |
---|
398 | uint8_t flags; /* Index header flags */ |
---|
399 | uint8_t reserved[3]; /* Align to 8-byte boundary */ |
---|
400 | } __attribute__((__packed__)); |
---|
401 | |
---|
402 | /* Attribute: Index Root (0x90) |
---|
403 | * Note: always resident |
---|
404 | */ |
---|
405 | struct ntfs_idx_root { |
---|
406 | uint32_t type; /* It is $FILE_NAME for directories, zero for view indexes. |
---|
407 | * No other values allowed. |
---|
408 | */ |
---|
409 | uint32_t collation_rule; |
---|
410 | uint32_t index_block_size; |
---|
411 | uint8_t clust_per_index_block; |
---|
412 | uint8_t reserved[3]; |
---|
413 | struct ntfs_idx_header index; |
---|
414 | } __attribute__((__packed__)); |
---|
415 | |
---|
416 | /* Attribute: Index allocation (0xA0) |
---|
417 | * Note: always non-resident, of course! :-) |
---|
418 | */ |
---|
419 | struct ntfs_idx_allocation { |
---|
420 | uint32_t magic; |
---|
421 | uint16_t usa_ofs; /* Update Sequence Array offsets */ |
---|
422 | uint16_t usa_count; /* Update Sequence Array number in bytes */ |
---|
423 | int64_t lsn; |
---|
424 | int64_t index_block_vcn; /* Virtual cluster number of the index block */ |
---|
425 | struct ntfs_idx_header index; |
---|
426 | } __attribute__((__packed__)); |
---|
427 | |
---|
428 | enum { |
---|
429 | INDEX_ENTRY_NODE = 1, |
---|
430 | INDEX_ENTRY_END = 2, |
---|
431 | /* force enum bit width to 16-bit */ |
---|
432 | INDEX_ENTRY_SPACE_FILTER = 0xFFFF, |
---|
433 | } __attribute__((__packed__)); |
---|
434 | |
---|
435 | struct ntfs_idx_entry_header { |
---|
436 | union { |
---|
437 | struct { /* Only valid when INDEX_ENTRY_END is not set */ |
---|
438 | uint64_t indexed_file; |
---|
439 | } __attribute__((__packed__)) dir; |
---|
440 | struct { /* Used for views/indexes to find the entry's data */ |
---|
441 | uint16_t data_offset; |
---|
442 | uint16_t data_len; |
---|
443 | uint32_t reservedV; |
---|
444 | } __attribute__((__packed__)) vi; |
---|
445 | } __attribute__((__packed__)) data; |
---|
446 | uint16_t len; |
---|
447 | uint16_t key_len; |
---|
448 | uint16_t flags; /* Index entry flags */ |
---|
449 | uint16_t reserved; /* Align to 8-byte boundary */ |
---|
450 | } __attribute__((__packed__)); |
---|
451 | |
---|
452 | struct ntfs_idx_entry { |
---|
453 | union { |
---|
454 | struct { /* Only valid when INDEX_ENTRY_END is not set */ |
---|
455 | uint64_t indexed_file; |
---|
456 | } __attribute__((__packed__)) dir; |
---|
457 | struct { /* Used for views/indexes to find the entry's data */ |
---|
458 | uint16_t data_offset; |
---|
459 | uint16_t data_len; |
---|
460 | uint32_t reservedV; |
---|
461 | } __attribute__((__packed__)) vi; |
---|
462 | } __attribute__((__packed__)) data; |
---|
463 | uint16_t len; |
---|
464 | uint16_t key_len; |
---|
465 | uint16_t flags; /* Index entry flags */ |
---|
466 | uint16_t reserved; /* Align to 8-byte boundary */ |
---|
467 | union { |
---|
468 | struct ntfs_filename_attr file_name; |
---|
469 | //SII_INDEX_KEY sii; |
---|
470 | //SDH_INDEX_KEY sdh; |
---|
471 | //GUID object_id; |
---|
472 | //REPARSE_INDEX_KEY reparse; |
---|
473 | //SID sid; |
---|
474 | uint32_t owner_id; |
---|
475 | } __attribute__((__packed__)) key; |
---|
476 | } __attribute__((__packed__)); |
---|
477 | |
---|
478 | static inline struct ntfs_sb_info *NTFS_SB(struct fs_info *fs) |
---|
479 | { |
---|
480 | return fs->fs_info; |
---|
481 | } |
---|
482 | |
---|
483 | #define NTFS_PVT(i) ((struct ntfs_inode *)((i)->pvt)) |
---|
484 | |
---|
485 | #endif /* _NTFS_H_ */ |
---|