1 /* Copyright © 2017-2018 Apple Inc. All rights reserved.
3 * livefiles_hfs_tester.c
6 * Created by Yakov Ben Zaken on 31/12/2017.
11 #include <mach/mach_time.h>
12 #include "livefiles_hfs_tester.h"
13 #include "lf_hfs_fsops_handler.h"
14 #include "lf_hfs_dirops_handler.h"
15 #include <UserFS/UserVFS.h>
17 #include <sys/queue.h>
18 #include "lf_hfs_journal.h"
19 #include "lf_hfs_generic_buf.h"
20 #include "lf_hfs_vfsutils.h"
21 #include "lf_hfs_raw_read_write.h"
23 #define DEFAULT_SYNCER_PERIOD 100 // mS
24 #define MAX_UTF8_NAME_LENGTH (NAME_MAX*3+1)
25 #define MAX_MAC2SFM (0x80)
26 #define TEST_CYCLE_COUNT (1)
27 #define CMP_TIMES(timspec1, timspec2) \
28 ((timspec1.tv_sec == timspec2.tv_sec) \
29 && (timspec1.tv_nsec == timspec2.tv_nsec))
31 #define ARR_LEN(arr) ((sizeof(arr))/(sizeof(arr[0])))
33 uint32_t guSyncerPeriod
= DEFAULT_SYNCER_PERIOD
;
35 typedef int (*test_hander_t
)( UVFSFileNode RootNode
);
38 typedef int (*TesterCrashAbortFunction_FP
)(void *psTestData
, CrashAbort_E eAbort
, int iFD
, UVFSFileNode psNode
, pthread_t bSyncerThread
);
46 test_hander_t pfTestHandler
;
48 UVFSFileNode psRootNode
;
49 pthread_t sSyncerThread
;
51 uint32_t uSyncerCount
;
55 uint32_t uCrashAbortCnt
;
56 CrashAbort_E eCrashID
;
57 TesterCrashAbortFunction_FP pAbortFunc
;
58 pthread_t sTestExeThread
;
66 pthread_t pSyncerThread
;
68 CrashAbort_E eCrashID
;
70 } TesterThreadReturnStatus_S
;
75 CrashAbort_E eCrashID
;
78 pthread_t pSyncerThread
;
83 char *ppcCrashAbortDesc
[CRASH_ABORT_LAST
] = {
84 [CRASH_ABORT_NONE
] = "None",
85 [CRASH_ABORT_MAKE_DIR
] = "Make Dir",
86 [CRASH_ABORT_JOURNAL_BEFORE_FINISH
] = "Journal, before transaction finish",
87 [CRASH_ABORT_JOURNAL_AFTER_JOURNAL_DATA
] = "Journal, after journal data has been written",
88 [CRASH_ABORT_JOURNAL_AFTER_JOURNAL_HEADER
] = "Journal, after journal header has been written",
89 [CRASH_ABORT_JOURNAL_IN_BLOCK_DATA
] = "Journal, while block data is being written",
90 [CRASH_ABORT_JOURNAL_AFTER_BLOCK_DATA
] = "Journal, after block data has been written",
91 [CRASH_ABORT_ON_UNMOUNT
] = "Unmount",
93 uint32_t guCrashAbortCnt
= 0;
94 CrashReport_S gsCrashReport
;
99 // Multi-thread read-write test
100 #if 1 // Quick Regression
101 #define MTRW_NUM_OF_THREADS 10
102 #define MTRW_FILE_SIZE 5*1000
103 #define MTRW_NUM_OF_FILES 10
104 #define MTRW_NUM_OF_SYMLINKS 10
105 #define MTRW_SYMLINK_SIZE PATH_MAX
106 #define MTRW_NUM_OF_OPERATIONS 10
107 #else // Longer Regression
108 #define MTRW_NUM_OF_THREADS 30
109 #define MTRW_FILE_SIZE 5*1000
110 #define MTRW_NUM_OF_FILES 30
111 #define MTRW_NUM_OF_SYMLINKS 30
112 #define MTRW_SYMLINK_SIZE PATH_MAX
113 #define MTRW_NUM_OF_OPERATIONS 30
118 UVFSFileNode psRootNode
;
119 uint32_t uNumOfFiles
;
120 uint32_t uNumOfSymLinks
;
121 uint32_t uSymLinkSize
;
127 static int SetAttrChangeSize(UVFSFileNode FileNode
,uint64_t uNewSize
);
128 static int SetAttrChangeMode(UVFSFileNode FileNode
,uint32_t uNewMode
);
129 static int SetAttrChangeUidGid(UVFSFileNode FileNode
, uint32_t uNewUid
, uint32_t uNewGid
);
130 static int SetAttrChangeAtimeMtime(UVFSFileNode FileNode
);
131 static int GetAttrAndCompare(UVFSFileNode FileNode
,UVFSFileAttributes
* sInAttrs
);
132 static int HFSTest_RunTest(TestData_S
*psTestData
);
133 static void *ReadWriteThread(void *pvArgs
);
143 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 00-07 */
144 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 08-0f */
145 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 10-17 */
146 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, /* 18-1f */
147 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, /* 20-27 */
148 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, /* 28-2f */
149 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 30-37 */
150 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, /* 38-3f */
151 0x40, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, /* 40-47 */
152 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, /* 48-4f */
153 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, /* 50-57 */
154 0x78, 0x79, 0x7a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, /* 58-5f */
155 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, /* 60-67 */
156 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, /* 68-6f */
157 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, /* 70-77 */
158 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, /* 78-7f */
159 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, /* 80-87 */
160 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, /* 88-8f */
161 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, /* 90-97 */
162 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, /* 98-9f */
163 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, /* a0-a7 */
164 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, /* a8-af */
165 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, /* b0-b7 */
166 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, /* b8-bf */
167 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, /* c0-c7 */
168 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, /* c8-cf */
169 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xd7, /* d0-d7 */
170 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xdf, /* d8-df */
171 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, /* e0-e7 */
172 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, /* e8-ef */
173 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, /* f0-f7 */
174 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, /* f8-ff */
178 * Macintosh Unicode (LSB) to Microsoft Services for Macintosh (SFM) Unicode
180 static const uint16_t
181 mac2sfm
[MAX_MAC2SFM
] = {
182 0x0, 0xf001, 0xf002, 0xf003, 0xf004, 0xf005, 0xf006, 0xf007, /* 00-07 */
183 0xf008, 0xf009, 0xf00a, 0xf00b, 0xf00c, 0xf00d, 0xf00e, 0xf00f, /* 08-0f */
184 0xf010, 0xf011, 0xf012, 0xf013, 0xf014, 0xf015, 0xf016, 0xf017, /* 10-17 */
185 0xf018, 0xf019, 0xf01a, 0xf01b, 0xf01c, 0xf01d, 0xf01e, 0xf01f, /* 18-1f */
186 0x20, 0x21, 0xf020, 0x23, 0x24, 0x25, 0x26, 0x27, /* 20-27 */
187 0x28, 0x29, 0xf021, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, /* 28-2f */
188 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 30-37 */
189 0x38, 0x39, 0xf022, 0x3b, 0xf023, 0x3d, 0xf024, 0xf025, /* 38-3f */
190 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 40-47 */
191 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, /* 48-4f */
192 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 50-57 */
193 0x58, 0x59, 0x5a, 0x5b, 0xf026, 0x5d, 0x5e, 0x5f, /* 58-5f */
194 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, /* 60-67 */
195 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, /* 68-6f */
196 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, /* 70-77 */
197 0x78, 0x79, 0x7a, 0x7b, 0xf027, 0x7d, 0x7e, 0x7f, /* 78-7f */
201 unistr255ToLowerCase( struct unistr255
* psUnistr255
)
203 for ( uint16_t uIdx
=0; uIdx
<psUnistr255
->length
; uIdx
++ )
205 if ( psUnistr255
->chars
[uIdx
] < 0x100 )
207 psUnistr255
->chars
[uIdx
] = l2u
[psUnistr255
->chars
[uIdx
]];
212 void HFSTest_PrintCacheStats(void) {
213 printf("Cache Statistics: buf_cache_size %u, max_buf_cache_size %u, buf_cache_cleanup %u, buf_cache_remove %u, max_gen_buf_uncached %u, gen_buf_uncached %u.\n",
214 gCacheStat
.buf_cache_size
,
215 gCacheStat
.max_buf_cache_size
,
216 gCacheStat
.buf_cache_cleanup
,
217 gCacheStat
.buf_cache_remove
,
218 gCacheStat
.max_gen_buf_uncached
,
219 gCacheStat
.gen_buf_uncached
);
222 __unused
static long long int timestamp()
224 /* Example of timestamp in second. */
225 time_t timestamp_sec
; /* timestamp in second */
226 time(×tamp_sec
); /* get current time; same as: timestamp_sec = time(NULL) */
228 /* Example of timestamp in microsecond. */
229 struct timeval timer_usec
;
230 long long int timestamp_usec
; /* timestamp in microsecond */
231 if (!gettimeofday(&timer_usec
, NULL
)) {
232 timestamp_usec
= ((long long int) timer_usec
.tv_sec
) * 1000000ll +
233 (long long int) timer_usec
.tv_usec
;
239 return timestamp_usec
;
242 __unused
static errno_t
243 CONV_UTF8ToUnistr255(const uint8_t *utf8
, size_t utf8Length
, struct unistr255
*unicode
)
249 for (i
= 0; i
< utf8Length
; ++i
)
252 if ((ch
& 0x80) == 0)
256 else if ((ch
& 0xE0) == 0xC0)
258 /* Two-byte sequence */
259 if (utf8Length
- i
>= 2 && (utf8
[i
+1] & 0xC0) == 0x80)
261 ch
= ((ch
<< 6) + utf8
[++i
]) - 0x3080;
265 /* Ill-formed UTF-8 */
269 else if ((ch
& 0xF0) == 0xE0)
271 /* Three-byte sequence */
272 if (utf8Length
- i
>= 3 && (utf8
[i
+1] & 0xC0) == 0x80 && (utf8
[i
+2] & 0xC0) == 0x80)
282 /* Ill-formed UTF-8 */
286 else if ((ch
& 0xF8) == 0xF0)
288 /* Four-byte sequence; requires surrogate pair for UTF-16 */
289 if (utf8Length
- i
>= 4 && (utf8
[i
+1] & 0xC0) == 0x80 && (utf8
[i
+2] & 0xC0) == 0x80 && (utf8
[i
+3] & 0xC0) == 0x80)
301 /* Ill-formed UTF-8 */
308 /* Requires surrogate pairs for UTF-16 */
309 if (unicode
->length
< 254)
312 unicode
->chars
[unicode
->length
++] = 0xD800 | (ch
>> 10);
313 unicode
->chars
[unicode
->length
++] = 0xDC00 | (ch
& 0x003F);
322 if (unicode
->length
< 255)
324 unicode
->chars
[unicode
->length
++] = ch
;
328 /* No room to store character */
334 //Only in "." and ".." we don't need to change the last char to speciel char.
335 bool bNeedToChangeLastChar
= true;
336 if ( ((unicode
->length
== 1) && (unicode
->chars
[0] == '.')) ||
337 ((unicode
->length
== 2) && (unicode
->chars
[0] == '.') && (unicode
->chars
[1] == '.')) )
339 bNeedToChangeLastChar
= false;
342 for ( uint16_t uIdx
=0; uIdx
<unicode
->length
; uIdx
++ )
344 //If the last char is "." or " " we need to change it.
345 //We won't use the mac2sfm table, we will do it manually
346 if ( bNeedToChangeLastChar
&& uIdx
== unicode
->length
-1 )
348 if ( unicode
->chars
[uIdx
] == ' ' )
350 unicode
->chars
[uIdx
] = 0xf028;
354 if ( unicode
->chars
[uIdx
] == '.' )
356 unicode
->chars
[uIdx
] = 0xf029;
362 if ( unicode
->chars
[uIdx
] < MAX_MAC2SFM
)
364 unicode
->chars
[uIdx
] = mac2sfm
[unicode
->chars
[uIdx
]];
371 __unused
static void print_dir_entry_name( uint32_t uLen
, char* pcName
, char* pcSearchName
, bool* pbFound
)
373 struct unistr255 sU255
;
374 struct unistr255 sU2552
;
375 memset( &sU255
, 0, sizeof(struct unistr255
));
376 memset( &sU2552
, 0, sizeof(struct unistr255
));
377 errno_t status
= CONV_UTF8ToUnistr255( (uint8_t*)pcName
, strlen(pcName
), &sU255
);
378 status
|= CONV_UTF8ToUnistr255( (uint8_t*)pcSearchName
, strlen(pcSearchName
), &sU2552
);
380 if ( status
!= 0 ) { assert(0); }
384 char pcNameToPrint
[uLen
+1];
385 memset( pcNameToPrint
, 0, sizeof(pcNameToPrint
) );
387 uint16_t* puName
= sU255
.chars
;
388 for ( uint32_t uIdx
=0; uIdx
<uLen
; uIdx
++ )
390 pcNameToPrint
[uIdx
] = *puName
++ & 0xff;
393 // printf( "TESTER Entry Name = [%s]\n", pcNameToPrint );
397 unistr255ToLowerCase(&sU255
);
398 unistr255ToLowerCase(&sU2552
);
400 if ( (sU255
.length
== sU2552
.length
) && !memcmp(sU255
.chars
, sU2552
.chars
, sU255
.length
*2) )
408 HFSTest_CompareReadDir( void* psReadEntry
, UVFSDirEntryAttr
* psExpectedAttr
, bool bIsWAttr
)
410 bool bIsEqual
= true;
413 UVFSDirEntryAttr
* psNewDirListEntry
= (UVFSDirEntryAttr
*) psReadEntry
;
414 if ( (strcmp(UVFS_DIRENTRYATTR_NAMEPTR(psExpectedAttr
),UVFS_DIRENTRYATTR_NAMEPTR(psNewDirListEntry
))) || // Comapre Name
415 (psNewDirListEntry
->dea_attrs
.fa_type
!= psExpectedAttr
->dea_attrs
.fa_type
) || // Comapre Type
416 (psNewDirListEntry
->dea_attrs
.fa_size
!= psExpectedAttr
->dea_attrs
.fa_size
) || // Comapre Size
417 (psNewDirListEntry
->dea_attrs
.fa_nlink
!= psExpectedAttr
->dea_attrs
.fa_nlink
) || // Compare Nlink
418 (psNewDirListEntry
->dea_attrs
.fa_mtime
.tv_sec
!= psExpectedAttr
->dea_attrs
.fa_mtime
.tv_sec
) || // Comapre MTime
419 (psNewDirListEntry
->dea_attrs
.fa_ctime
.tv_sec
!= psExpectedAttr
->dea_attrs
.fa_ctime
.tv_sec
) || // Comapre Ctime
420 (psNewDirListEntry
->dea_attrs
.fa_atime
.tv_sec
!= psExpectedAttr
->dea_attrs
.fa_atime
.tv_sec
) || // Comapre Atime
421 (psNewDirListEntry
->dea_attrs
.fa_birthtime
.tv_sec
!= psExpectedAttr
->dea_attrs
.fa_birthtime
.tv_sec
) || // Comapre birthtime
422 (psNewDirListEntry
->dea_attrs
.fa_mtime
.tv_nsec
!= psExpectedAttr
->dea_attrs
.fa_mtime
.tv_nsec
) || // Comapre MTime
423 (psNewDirListEntry
->dea_attrs
.fa_ctime
.tv_nsec
!= psExpectedAttr
->dea_attrs
.fa_ctime
.tv_nsec
) || // Comapre Ctime
424 (psNewDirListEntry
->dea_attrs
.fa_atime
.tv_nsec
!= psExpectedAttr
->dea_attrs
.fa_atime
.tv_nsec
) || // Comapre Atime
425 (psNewDirListEntry
->dea_attrs
.fa_birthtime
.tv_nsec
!= psExpectedAttr
->dea_attrs
.fa_birthtime
.tv_nsec
) || // Comapre birthtime
426 (psNewDirListEntry
->dea_attrs
.fa_allocsize
!= psExpectedAttr
->dea_attrs
.fa_allocsize
) )
428 printf("HFSTest_CompareReadDir: failed.\n");
430 printf("HFSTest_CompareReadDir: expected- name [%s], type [%d], size [%llu], nlink [%u], allocsize [%llu].\n",UVFS_DIRENTRYATTR_NAMEPTR(psExpectedAttr
), psExpectedAttr
->dea_attrs
.fa_type
, psExpectedAttr
->dea_attrs
.fa_size
, psExpectedAttr
->dea_attrs
.fa_nlink
, psExpectedAttr
->dea_attrs
.fa_allocsize
);
431 printf("HFSTest_CompareReadDir: expected- mtime [%ld.%ld], ctime [%ld.%ld], atime [%ld.%ld], btime [%ld.%ld] .\n",psExpectedAttr
->dea_attrs
.fa_mtime
.tv_sec
,psExpectedAttr
->dea_attrs
.fa_mtime
.tv_nsec
,psExpectedAttr
->dea_attrs
.fa_ctime
.tv_sec
,psExpectedAttr
->dea_attrs
.fa_ctime
.tv_nsec
, psExpectedAttr
->dea_attrs
.fa_atime
.tv_sec
, psExpectedAttr
->dea_attrs
.fa_atime
.tv_nsec
, psExpectedAttr
->dea_attrs
.fa_birthtime
.tv_sec
, psExpectedAttr
->dea_attrs
.fa_birthtime
.tv_nsec
);
433 printf("HFSTest_CompareReadDir: got - name [%s], type [%d], size [%llu], nlink [%u], allocsize [%llu].\n",UVFS_DIRENTRYATTR_NAMEPTR(psNewDirListEntry
), psNewDirListEntry
->dea_attrs
.fa_type
, psNewDirListEntry
->dea_attrs
.fa_size
, psNewDirListEntry
->dea_attrs
.fa_nlink
, psNewDirListEntry
->dea_attrs
.fa_allocsize
);
434 printf("HFSTest_CompareReadDir: got - mtime [%ld.%ld], ctime [%ld.%ld], atime [%ld.%ld], btime [%ld.%ld] .\n",psNewDirListEntry
->dea_attrs
.fa_mtime
.tv_sec
,psNewDirListEntry
->dea_attrs
.fa_mtime
.tv_nsec
,psNewDirListEntry
->dea_attrs
.fa_ctime
.tv_sec
,psNewDirListEntry
->dea_attrs
.fa_ctime
.tv_nsec
, psNewDirListEntry
->dea_attrs
.fa_atime
.tv_sec
,psNewDirListEntry
->dea_attrs
.fa_atime
.tv_nsec
, psNewDirListEntry
->dea_attrs
.fa_birthtime
.tv_sec
,psNewDirListEntry
->dea_attrs
.fa_birthtime
.tv_nsec
);
441 UVFSDirEntry
* psNewDirListEntry
= ( UVFSDirEntry
*) psReadEntry
;
442 if ( (strcmp(UVFS_DIRENTRYATTR_NAMEPTR(psExpectedAttr
),psNewDirListEntry
->de_name
)) || // Comapre Name
443 (psNewDirListEntry
->de_filetype
!= psExpectedAttr
->dea_attrs
.fa_type
)) // Comapre Type
454 /* --------------------------------------------------------------------------------------------- */
455 static void SetExpectedAttr(char* pcName
, uint32_t uType
, UVFSDirEntryAttr
* psAttr
);
456 static int ReadDirAttr(UVFSFileNode psNode
, UVFSDirEntryAttr
* psReadDirTestsData
, uint32_t uDirEntries
);
457 static int RemoveFolder(UVFSFileNode ParentNode
,char* DirNameToRemove
);
458 static int CreateNewFolder(UVFSFileNode ParentNode
,UVFSFileNode
* NewDirNode
,char* NewDirName
);
459 static int CreateHardLink(UVFSFileNode FromNode
, UVFSFileNode ToDirNode
, char* NewHardLinkName
);
460 static int RemoveFile(UVFSFileNode ParentNode
,char* FileNameToRemove
);
461 static int CreateNewFile(UVFSFileNode ParentNode
,UVFSFileNode
* NewFileNode
,char* NewFileName
,uint64_t size
);
462 static int read_directory_and_search_for_name( UVFSFileNode psNode
, char* pcSearchName
, bool* pbFound
, UVFSDirEntryAttr
* psReadDirTestsData
, uint32_t uDirEntries
);
463 static int RenameFile(UVFSFileNode FromParentNode
,UVFSFileNode FromNode
,char* FromName
, UVFSFileNode ToParentNode
,UVFSFileNode ToNode
,char* ToName
);
464 /* --------------------------------------------------------------------------------------------- */
466 static int RemoveFolder(UVFSFileNode ParentNode
,char* DirNameToRemove
)
470 error
= HFS_fsOps
.fsops_rmdir(ParentNode
, DirNameToRemove
);;
475 static int RemoveFile(UVFSFileNode ParentNode
,char* FileNameToRemove
)
479 error
= HFS_fsOps
.fsops_remove( ParentNode
, FileNameToRemove
, NULL
);
484 static int RenameFile(UVFSFileNode FromParentNode
,UVFSFileNode FromNode
,char* FromName
, UVFSFileNode ToParentNode
,UVFSFileNode ToNode
,char* ToName
)
488 error
= HFS_fsOps
.fsops_rename( FromParentNode
, FromNode
, FromName
, ToParentNode
, ToNode
, ToName
, 0);
493 static int CreateNewFile(UVFSFileNode ParentNode
,UVFSFileNode
* NewFileNode
,char* NewFileName
,uint64_t size
)
496 UVFSFileAttributes attrs
= {0};
498 attrs
.fa_validmask
= UVFS_FA_VALID_MODE
| UVFS_FA_VALID_SIZE
;
499 attrs
.fa_type
= UVFS_FA_TYPE_FILE
;
500 attrs
.fa_mode
= UVFS_FA_MODE_OTH(UVFS_FA_MODE_RWX
)|UVFS_FA_MODE_GRP(UVFS_FA_MODE_RWX
)|UVFS_FA_MODE_USR(UVFS_FA_MODE_RWX
);;
501 attrs
.fa_size
= size
;
503 error
= HFS_fsOps
.fsops_create(ParentNode
, NewFileName
, &attrs
, NewFileNode
);
508 static int CreateNewFolder(UVFSFileNode ParentNode
,UVFSFileNode
* NewDirNode
,char* NewDirName
)
512 UVFSFileAttributes attrs
;
513 memset(&attrs
,0,sizeof(UVFSFileAttributes
));
514 attrs
.fa_validmask
= UVFS_FA_VALID_MODE
;
515 attrs
.fa_type
= UVFS_FA_TYPE_DIR
;
516 attrs
.fa_mode
= UVFS_FA_MODE_OTH(UVFS_FA_MODE_RWX
)|UVFS_FA_MODE_GRP(UVFS_FA_MODE_RWX
)|UVFS_FA_MODE_USR(UVFS_FA_MODE_RWX
);
517 error
= HFS_fsOps
.fsops_mkdir(ParentNode
, NewDirName
, &attrs
, NewDirNode
);
522 static int CreateHardLink(UVFSFileNode FromNode
, UVFSFileNode ToDirNode
, char* NewHardLinkName
)
526 UVFSFileAttributes sToDirAttrs
;
527 UVFSFileAttributes sFromNodeAttrs
;
528 memset(&sToDirAttrs
,0,sizeof(UVFSFileAttributes
));
529 memset(&sFromNodeAttrs
,0,sizeof(UVFSFileAttributes
));
531 error
= HFS_fsOps
.fsops_link(FromNode
, ToDirNode
, NewHardLinkName
, &sFromNodeAttrs
, &sToDirAttrs
);
536 static int read_directory_and_search_for_name( UVFSFileNode psNode
, char* pcSearchName
, bool* pbFound
, UVFSDirEntryAttr
* psReadDirTestsData
, uint32_t uDirEntries
)
538 if (pbFound
) *pbFound
= false;
540 uint32_t uBufferSize
= 1000;
541 uint8_t* puBuffer
= malloc(uBufferSize
*2);
542 if ( puBuffer
== NULL
)
546 memset(puBuffer
, 0xff, uBufferSize
*2);
548 uint64_t uCookie
= 0;
549 uint64_t uVerifier
= UVFS_DIRCOOKIE_VERIFIER_INITIAL
;
550 bool bConRead
= true;
552 uint32_t uDirsCounter
= 0;
553 uint32_t uFilesCounter
= 0;
554 uint32_t uLinksCounter
= 0;
556 uint32_t uDirIndex
= 0;
558 UVFSDirEntryAttr
* psDirData
= psReadDirTestsData
;
561 uint32_t uBufCurOffset
= 0;
563 memset(puBuffer
, 0, uBufferSize
);
565 iReadDirERR
= HFS_fsOps
.fsops_readdir (psNode
, puBuffer
, uBufferSize
, uCookie
, &outLen
, &uVerifier
);
566 // assert(0xffffffffffffffff == *(uint64_t*)(&puBuffer[100]));
567 if ( (iReadDirERR
!= 0 && iReadDirERR
!= UVFS_READDIR_EOF_REACHED
) || outLen
==0)
573 //Go over all entries in the list and check if we got to the end of the directory
574 bool bEndOfDirectoryList
= false;
576 while ( !bEndOfDirectoryList
&& iReadDirERR
!= UVFS_READDIR_EOF_REACHED
)
578 UVFSDirEntry
* psNewDirListEntry
= (UVFSDirEntry
*) &puBuffer
[uBufCurOffset
];
579 uCookie
= psNewDirListEntry
->de_nextcookie
;
581 //We found all the files in the root directory
582 if ( ( psNewDirListEntry
->de_nextcookie
== UVFS_DIRCOOKIE_EOF
) || ( psNewDirListEntry
->de_reclen
== 0 ) )
584 bEndOfDirectoryList
= true;
587 print_dir_entry_name( psNewDirListEntry
->de_namelen
, psNewDirListEntry
->de_name
, pcSearchName
, pbFound
);
588 switch ( psNewDirListEntry
->de_filetype
)
590 case UVFS_FA_TYPE_DIR
:
592 //printf("found dir: ID: %llu, named [%s], in offset [%u]\n",psNewDirListEntry->de_fileid, psNewDirListEntry->de_name, uBufCurOffset);
596 case UVFS_FA_TYPE_FILE
:
598 //printf("found file: ID: %llu, named [%s], in offset [%u]\n",psNewDirListEntry->de_fileid, psNewDirListEntry->de_name, uBufCurOffset);
602 case UVFS_FA_TYPE_SYMLINK
:
604 //printf("found link: ID: %llu, named [%s], in offset [%u]\n",psNewDirListEntry->de_fileid, psNewDirListEntry->de_name, uBufCurOffset);
610 printf("Found Unkown file type %d, named [%s], Exiting\n", psNewDirListEntry
->de_filetype
, psNewDirListEntry
->de_name
);
611 bEndOfDirectoryList
= true;
616 if (psDirData
!= NULL
)
618 printf("Expected FileName = [%s], FileType = [%d].\n", UVFS_DIRENTRYATTR_NAMEPTR(psDirData
), psDirData
->dea_attrs
.fa_type
);
620 //TBD - When getAttr will work need to change the compare to getAttr vs ReadDirAttr
621 if ( !HFSTest_CompareReadDir(psNewDirListEntry
, psDirData
, false) )
623 iReadDirERR
= EINVAL
;
627 assert(uDirIndex
<uDirEntries
);
629 psDirData
= (UVFSDirEntryAttr
*) ((void*) psDirData
+ sizeof(UVFSDirEntryAttr
) + MAX_UTF8_NAME_LENGTH
);
632 uBufCurOffset
+= UVFS_DIRENTRY_RECLEN(strlen(psNewDirListEntry
->de_name
));
635 } while( bConRead
&& (iReadDirERR
!= UVFS_READDIR_EOF_REACHED
) );
637 if ( puBuffer
) free( puBuffer
);
639 if(iReadDirERR
== UVFS_READDIR_EOF_REACHED
)
643 assert(uDirIndex
==uDirEntries
);
649 ReadDirAttr( UVFSFileNode psNode
, UVFSDirEntryAttr
* psReadDirTestsData
, uint32_t uDirEntries
)
651 uint32_t uBufferSize
= 1000;
652 uint8_t* puBuffer
= malloc(uBufferSize
);
653 if ( puBuffer
== NULL
)
658 uint64_t uCookie
= 0;
659 uint64_t uVerifier
= UVFS_DIRCOOKIE_VERIFIER_INITIAL
;
660 bool bConRead
= true;
663 uint32_t uDirIndex
= 0;
664 UVFSDirEntryAttr
* psReadDir
= psReadDirTestsData
;
668 uint32_t uBufCurOffset
= 0;
670 memset(puBuffer
, 0, uBufferSize
);
672 iReadDirERR
= HFS_fsOps
.fsops_readdirattr (psNode
, puBuffer
, uBufferSize
, uCookie
, &outLen
, &uVerifier
);
673 if ( (iReadDirERR
!= 0 && iReadDirERR
!= UVFS_READDIR_EOF_REACHED
) || (outLen
== 0) )
679 //Go over all entries in the list and check if we got to the end of the directory
680 bool bEndOfDirectoryList
= false;
682 while ( !bEndOfDirectoryList
&& iReadDirERR
!= UVFS_READDIR_EOF_REACHED
)
684 UVFSDirEntryAttr
* psNewDirListEntry
= (UVFSDirEntryAttr
*) &puBuffer
[uBufCurOffset
];
685 uCookie
= psNewDirListEntry
->dea_nextcookie
;
686 //We found all the files in the root directory
687 if ( ( psNewDirListEntry
->dea_nextcookie
== UVFS_DIRCOOKIE_EOF
) || ( psNewDirListEntry
->dea_nextrec
== 0 ) )
689 bEndOfDirectoryList
= true;
692 printf("Found FileName = [%s], FileID = [%llu], FileSize = [%llu].\n", UVFS_DIRENTRYATTR_NAMEPTR(psNewDirListEntry
), psNewDirListEntry
->dea_attrs
.fa_fileid
, psNewDirListEntry
->dea_attrs
.fa_size
);
694 if (psReadDir
!= NULL
)
696 printf("Expected FileName = [%s], FileType = [%d].\n", UVFS_DIRENTRYATTR_NAMEPTR(psReadDir
), psReadDir
->dea_attrs
.fa_type
);
698 //TBD - When getAttr will work need to change the compare to getAttr vs ReadDirAttr
699 if ( !HFSTest_CompareReadDir((void*)psNewDirListEntry
, psReadDir
, true) )
701 iReadDirERR
= EINVAL
;
705 assert( uDirIndex
< uDirEntries
);
707 psReadDir
= (UVFSDirEntryAttr
*) ((void*) psReadDir
+ sizeof(UVFSDirEntryAttr
) + MAX_UTF8_NAME_LENGTH
);
710 uBufCurOffset
+= UVFS_DIRENTRYATTR_RECLEN(psNewDirListEntry
, strlen(UVFS_DIRENTRYATTR_NAMEPTR(psNewDirListEntry
)));
713 } while( bConRead
&& (iReadDirERR
!= UVFS_READDIR_EOF_REACHED
) );
718 if(iReadDirERR
== UVFS_READDIR_EOF_REACHED
)
721 if (psReadDir
!= NULL
)
722 assert( uDirIndex
== uDirEntries
);
728 GetAttrAndCompare(UVFSFileNode FileNode
,UVFSFileAttributes
* sInAttrs
)
731 UVFSFileAttributes sOutAttrs
;
732 error
= HFS_fsOps
.fsops_getattr(FileNode
, &sOutAttrs
);
735 printf("Failed in get attr with err [%d]\n",error
);
738 if (sInAttrs
->fa_validmask
& UVFS_FA_VALID_SIZE
)
739 if (sOutAttrs
.fa_size
!= sInAttrs
->fa_size
)
742 if (sInAttrs
->fa_validmask
& UVFS_FA_VALID_MODE
)
743 if (sOutAttrs
.fa_mode
!= sInAttrs
->fa_mode
)
746 if (sInAttrs
->fa_validmask
& UVFS_FA_VALID_BSD_FLAGS
)
747 if (sOutAttrs
.fa_bsd_flags
!= sInAttrs
->fa_bsd_flags
)
750 if (sInAttrs
->fa_validmask
& UVFS_FA_VALID_ATIME
)
751 if (CMP_TIMES(sOutAttrs
.fa_atime
,sInAttrs
->fa_atime
))
754 if (sInAttrs
->fa_validmask
& UVFS_FA_VALID_MTIME
)
755 if (CMP_TIMES(sOutAttrs
.fa_atime
,sInAttrs
->fa_atime
))
758 if (sInAttrs
->fa_validmask
& UVFS_FA_VALID_CTIME
)
759 if (CMP_TIMES(sOutAttrs
.fa_ctime
, sInAttrs
->fa_ctime
))
762 if (sInAttrs
->fa_validmask
& UVFS_FA_VALID_BIRTHTIME
)
763 if (CMP_TIMES(sOutAttrs
.fa_birthtime
, sInAttrs
->fa_birthtime
))
771 if (error
) printf("Failed in compare attr\n");
776 SetAttrChangeSize(UVFSFileNode FileNode
,uint64_t uNewSize
)
779 UVFSFileAttributes sInAttrs
;
780 UVFSFileAttributes sOutAttrs
;
781 memset(&sInAttrs
,0,sizeof(UVFSFileAttributes
));
782 sInAttrs
.fa_validmask
|= UVFS_FA_VALID_SIZE
;
783 sInAttrs
.fa_size
= uNewSize
;
785 error
= HFS_fsOps
.fsops_setattr( FileNode
, &sInAttrs
, &sOutAttrs
);
787 error
= GetAttrAndCompare(FileNode
,&sInAttrs
);
793 SetAttrChangeMode(UVFSFileNode FileNode
,uint32_t uNewMode
)
796 UVFSFileAttributes sInAttrs
;
797 UVFSFileAttributes sOutAttrs
;
798 memset(&sInAttrs
,0,sizeof(UVFSFileAttributes
));
799 sInAttrs
.fa_validmask
|= UVFS_FA_VALID_MODE
;
800 sInAttrs
.fa_mode
= uNewMode
;
802 error
= HFS_fsOps
.fsops_setattr( FileNode
, &sInAttrs
, &sOutAttrs
);
808 SetAttrChangeUidGid(UVFSFileNode FileNode
, uint32_t uNewUid
, uint32_t uNewGid
)
811 UVFSFileAttributes sInAttrs
;
812 UVFSFileAttributes sOutAttrs
;
813 memset(&sInAttrs
,0,sizeof(UVFSFileAttributes
));
814 sInAttrs
.fa_validmask
|= UVFS_FA_VALID_UID
;
815 sInAttrs
.fa_validmask
|= UVFS_FA_VALID_GID
;
816 sInAttrs
.fa_uid
= uNewUid
;
817 sInAttrs
.fa_gid
= uNewGid
;
819 error
= HFS_fsOps
.fsops_setattr( FileNode
, &sInAttrs
, &sOutAttrs
);
825 SetAttrChangeAtimeMtime(UVFSFileNode FileNode
)
828 UVFSFileAttributes sInAttrs
;
829 UVFSFileAttributes sOutAttrs
;
831 error
= HFS_fsOps
.fsops_getattr(FileNode
, &sOutAttrs
);
834 printf("Failed in get attr (1) with err [%d]\n",error
);
838 memset(&sInAttrs
,0,sizeof(UVFSFileAttributes
));
839 sInAttrs
.fa_validmask
|= UVFS_FA_VALID_ATIME
;
840 sInAttrs
.fa_validmask
|= UVFS_FA_VALID_MTIME
;
841 sInAttrs
.fa_atime
.tv_sec
= sOutAttrs
.fa_atime
.tv_sec
+ 90000000;
842 sInAttrs
.fa_mtime
.tv_sec
= sOutAttrs
.fa_mtime
.tv_sec
+ 90000000;
844 error
= HFS_fsOps
.fsops_setattr( FileNode
, &sInAttrs
, &sOutAttrs
);
848 printf("Failed to set attr to change atime and mtime err [%d]", error
);
851 error
= HFS_fsOps
.fsops_getattr(FileNode
, &sOutAttrs
);
854 printf("Failed in get attr (2) with err [%d]\n",error
);
858 if ( (sOutAttrs
.fa_atime
.tv_sec
!= sInAttrs
.fa_atime
.tv_sec
) || (sOutAttrs
.fa_mtime
.tv_sec
!= sInAttrs
.fa_mtime
.tv_sec
) )
860 printf("Failed to update time!\n");
866 /*******************************************/
867 /*******************************************/
868 /*******************************************/
869 // Predefined Tests START.
870 /*******************************************/
871 /*******************************************/
872 /*******************************************/
874 #define HFS_TEST_PREFIX "RUN_HFS_TESTS"
875 #define HFS_RUN_FSCK "RUN_FSCK"
876 #define HFS_DMGS_FOLDER "/Volumes/SSD_Shared/FS_DMGs/"
877 #define TEMP_DMG "/tmp/hfstester.dmg"
878 #define TEMP_DMG_SPARSE "/tmp/hfstester.dmg.sparseimage"
879 #define TEMP_DMG_BKUP "/tmp/hfstester_bkup.dmg"
880 #define TEMP_DMG_BKUP_SPARSE "/tmp/hfstester_bkup.dmg.sparseimage"
881 #define TEMP_DEV_PATH "/tmp/dev_path.txt"
882 #define TEMP_DEV_PATH2 "/tmp/dev_path2.txt"
883 #define TEMP_DEV_PATH3 "/tmp/dev_path3.txt"
884 #define CREATE_SPARSE_VOLUME "CREATE_SPARSE_VOLUME"
885 #define CREATE_HFS_DMG "CREATE_HFS_DMG"
887 #define MAX_CMN_LEN (1024*2)
889 typedef int (*test_hander_t
)( UVFSFileNode RootNode
);
891 char pcLastDevPathName
[50] = {0};
892 char pcDevPath
[50] = {0};
893 char pcDevNum
[50] = {0};
894 char gpcResultsFolder
[256] = {0};
897 HFSTest_PrepareEnv(TestData_S
*psTestData
)
900 bool bMountedAlready
= false;
901 char* pcCmd
= malloc(MAX_CMN_LEN
);
904 // Remove old dmg if exist.
905 strcpy(pcCmd
, "rm -rf ");
906 strcat(pcCmd
, TEMP_DMG
" "TEMP_DEV_PATH
" "TEMP_DEV_PATH2
" "TEMP_DMG_SPARSE
);
908 if (psTestData
->eCrashID
) {
909 strcat(pcCmd
, " "TEMP_DMG_BKUP
" "TEMP_DMG_BKUP_SPARSE
);
912 printf("Execute %s:\n", pcCmd
);
915 if (!strcmp(CREATE_SPARSE_VOLUME
, psTestData
->pcDMGPath
)) {
916 // Create a spase volume
917 psTestData
->bSparseImage
= true;
918 strcpy(pcCmd
, "hdiutil create -ov -size 20G -type SPARSE -layout NONE ");
919 strcat(pcCmd
, TEMP_DMG
);
920 printf("Execute %s:\n", pcCmd
);
921 iErr
= system( pcCmd
);
926 strcpy(pcCmd
, "hdiutil attach -nomount ");
927 strcat(pcCmd
, TEMP_DMG_SPARSE
" > "TEMP_DEV_PATH
);
928 printf("Execute %s:\n", pcCmd
);
929 iErr
= system( pcCmd
);
934 bMountedAlready
= true;
936 // Extract disk number (disk??)
937 strcpy(pcCmd
, "cat "TEMP_DEV_PATH
" | sed 's/\\/dev\\/disk\\([0-9]*\\)/\\1/' | awk '{print $1}' > "TEMP_DEV_PATH2
);
938 printf("Execute %s:\n", pcCmd
);
939 iErr
= system( pcCmd
);
944 FILE *psCat
= fopen(TEMP_DEV_PATH2
, "r");
945 fgets(pcLastDevPathName
, sizeof(pcLastDevPathName
), psCat
);
947 pcLastDevPathName
[strlen(pcLastDevPathName
)-1] = '\0';
949 sprintf(pcCmd
, "newfs_hfs -v SparsedVolume -J /dev/disk%s ", pcLastDevPathName
);
950 printf("Execute %s:\n", pcCmd
);
951 iErr
= system( pcCmd
);
956 strcpy(pcDevPath
, "/dev/rdisk");
957 strcat(pcDevPath
, pcLastDevPathName
);
958 printf("%s\n", pcDevPath
);
961 } else if (!strcmp(CREATE_HFS_DMG
, psTestData
->pcDMGPath
)) {
962 // No dmg filename provided. Create one:
963 strcpy(pcCmd
, "hdiutil create -size 20G -fs HFS+ -volname TwentyGigDmg ");
964 strcat(pcCmd
, TEMP_DMG
);
965 printf("Execute %s:\n", pcCmd
);
966 iErr
= system( pcCmd
);
972 } else if (psTestData
->pcDMGPath
[0] == '\0') {
973 // No dmg filename provided. Create one:
974 strcpy(pcCmd
, "hdiutil create -size 20G -fs HFS+J -volname TwentyGigJournalDmg ");
975 strcat(pcCmd
, TEMP_DMG
);
976 printf("Execute %s:\n", pcCmd
);
977 iErr
= system( pcCmd
);
983 // use dmg from provided path
984 psTestData
->bSparseImage
= (strstr(psTestData
->pcDMGPath
, ".sparseimage") != NULL
);
985 // Copy dmg to tmp folder
986 strcpy(pcCmd
, "cp ");
987 strcat(pcCmd
, psTestData
->pcDMGPath
);
989 if (psTestData
->bSparseImage
) {
990 strcat(pcCmd
, TEMP_DMG_SPARSE
);
992 strcat(pcCmd
, TEMP_DMG
);
994 printf("Execute %s:\n", pcCmd
);
995 iErr
= system( pcCmd
);
1002 if (!bMountedAlready
) {
1004 strcpy(pcCmd
, "hdiutil attach -nomount ");
1005 if (psTestData
->bSparseImage
) {
1006 strcat(pcCmd
, TEMP_DMG_SPARSE
);
1008 strcat(pcCmd
, TEMP_DMG
);
1010 strcat(pcCmd
," > ");
1011 strcat(pcCmd
, TEMP_DEV_PATH
);
1012 printf("Execute %s:\n", pcCmd
);
1013 iErr
= system( pcCmd
);
1019 // Do we have multiple partitions?
1020 strcpy(pcCmd
, "cat "TEMP_DEV_PATH
" | grep Apple_HFS > "TEMP_DEV_PATH2
);
1021 printf("Execute %s:\n", pcCmd
);
1022 int iSinglePartition
= system( pcCmd
);
1024 if (iSinglePartition
) {
1025 // Extract disk number (disk??)
1026 strcpy(pcCmd
, "cat "TEMP_DEV_PATH
" | sed 's/\\/dev\\/disk\\([0-9]*\\)/\\1/' | awk '{print $1}' > "TEMP_DEV_PATH2
);
1027 printf("Execute %s:\n", pcCmd
);
1028 iErr
= system( pcCmd
);
1033 FILE *psCat
= fopen(TEMP_DEV_PATH2
, "r");
1034 fgets(pcLastDevPathName
, sizeof(pcLastDevPathName
), psCat
);
1036 pcLastDevPathName
[strlen(pcLastDevPathName
)-1] = '\0';
1038 // Generate the full path
1040 strcpy(pcDevPath
, "/dev/rdisk");
1041 strcat(pcDevPath
, pcLastDevPathName
);
1042 printf("%s\n", pcDevPath
);
1044 } else { // Multilpe partitions
1045 // Extract disk number (disk??)
1046 strcpy(pcCmd
, "cat "TEMP_DEV_PATH
" | grep Apple_HFS | sed 's/\\/dev\\/disk\\([0-9]*\\)s[0-9]*/\\1/' | awk '{print $1}' > "TEMP_DEV_PATH2
);
1047 printf("Execute %s:\n", pcCmd
);
1048 iErr
= system( pcCmd
);
1053 FILE *psCat
= fopen(TEMP_DEV_PATH2
, "r");
1054 fgets(pcLastDevPathName
, sizeof(pcLastDevPathName
), psCat
);
1056 pcLastDevPathName
[strlen(pcLastDevPathName
)-1] = '\0';
1058 // Extract s number (s??)
1059 strcpy(pcCmd
, "cat "TEMP_DEV_PATH
" | grep Apple_HFS | sed 's/\\/dev\\/disk[0-9]*s\\([0-9]*\\)/\\1/' | awk '{print $1}' > "TEMP_DEV_PATH3
);
1060 printf("Execute %s:\n", pcCmd
);
1061 iErr
= system( pcCmd
);
1066 psCat
= fopen(TEMP_DEV_PATH3
, "r");
1067 fgets(pcDevNum
, sizeof(pcDevNum
), psCat
);
1069 pcDevNum
[strlen(pcDevNum
)-1] = '\0';
1071 // Generate the full path
1072 strcpy(pcDevPath
, "/dev/rdisk");
1073 strcat(pcDevPath
, pcLastDevPathName
);
1074 strcat(pcDevPath
, "s");
1075 strcat(pcDevPath
, pcDevNum
);
1076 printf("%s\n", pcDevPath
);
1082 printf("pcDevPath is %s\n", pcDevPath
);
1083 int iFD
= open( pcDevPath
, O_RDWR
);
1086 printf("Failed to open %s\n", pcDevPath
);
1096 HFSTest_DestroyEnv(__unused
int iFD
)
1099 char* pcCmd
= malloc(MAX_CMN_LEN
);
1103 memset(pcCmd
, 0, MAX_CMN_LEN
);
1104 strcat(pcCmd
, "hdiutil detach /dev/disk");
1105 strcat(pcCmd
, pcLastDevPathName
);
1106 printf("Execute %s:\n", pcCmd
);
1107 iErr
= system(pcCmd
);
1113 // Remove old dmg if exist.
1114 memset(pcCmd
, 0, MAX_CMN_LEN
);
1115 strcat(pcCmd
, "rm -rf ");
1116 strcat(pcCmd
, TEMP_DEV_PATH
);
1118 strcat(pcCmd
, TEMP_DEV_PATH2
);
1119 printf("Execute %s:\n", pcCmd
);
1126 void HFSTest_ClearCrashAbortFunctionArray(void) {
1127 for(unsigned u
=0; u
<CRASH_ABORT_LAST
; u
++)
1128 gpsCrashAbortFunctionArray
[u
] = NULL
;
1132 char pcMountedDev
[512];
1133 char pcMountedVol
[512];
1136 int HFSTest_KextMount(char *pcDmgFilename
, MountedDrive_S
*psMntd
, bool bMount
) {
1139 char pcMountCmd
[512] = {0};
1140 strcat( pcMountCmd
, "hdiutil attach ");
1142 strcat( pcMountCmd
, "-nomount ");
1144 strcat( pcMountCmd
, "-plist ");
1145 strcat( pcMountCmd
, pcDmgFilename
);
1146 strcat( pcMountCmd
, " > /tmp/tmp.txt ");
1147 printf("Execute %s:\n", pcMountCmd
);
1148 iErr
= system(pcMountCmd
);
1149 printf("*** %s returned %d\n", pcMountCmd
,iErr
);
1153 char pcCatCmd
[512] = {0};
1154 strcat( pcCatCmd
, "cat /tmp/tmp.txt | grep '\\/dev\\/disk[0-9]*' | tr -d '\\t' | sed 's/<string>//' | sed 's/<\\/string>//' > /tmp/dev.txt");
1155 printf("Execute %s:\n", pcCatCmd
);
1156 iErr
= system(pcCatCmd
);
1157 printf("returned %d\n", iErr
);
1161 psMntd
->pcMountedDev
[0] = '\0';
1162 FILE *psCat
= fopen("/tmp/dev.txt", "r");
1163 fscanf(psCat
, "%s", psMntd
->pcMountedDev
);
1165 printf("pcMountedDev is %s\n", psMntd
->pcMountedDev
);
1167 strcpy( pcCatCmd
, "cat /tmp/tmp.txt | grep '\\/Volumes' | tr -d '\\t' | sed 's/<string>//' | sed 's/<\\/string>//' > /tmp/vol.txt");
1168 printf("Execute %s:\n", pcCatCmd
);
1169 iErr
= system(pcCatCmd
);
1170 printf("returned %d\n", iErr
);
1174 psCat
= fopen("/tmp/vol.txt", "r");
1175 strcpy(psMntd
->pcMountedVol
, "\"");
1176 fscanf(psCat
, "%[^\n]", &psMntd
->pcMountedVol
[1]);
1177 strcat(psMntd
->pcMountedVol
, "\"");
1179 printf("pcMountedVol is %s\n", psMntd
->pcMountedVol
);
1184 int HFSTest_KextFindAll(MountedDrive_S
*psMntd
, char *pcSearchFile
) {
1187 char pcFindCmd
[512] = {0};
1188 sprintf(pcFindCmd
, "find %s | tee /tmp/file-list.txt", psMntd
->pcMountedVol
);
1189 printf("Execute %s :\n", pcFindCmd
);
1190 iErr
= system(pcFindCmd
);
1191 printf("returned %d\n", iErr
);
1195 sprintf(pcFindCmd
, "cat /tmp/file-list.txt | grep %s", pcSearchFile
);
1196 printf("Execute %s :\n", pcFindCmd
);
1197 iErr
= system(pcFindCmd
);
1198 printf("returned %d\n", iErr
);
1205 int HFSTest_KextCount(MountedDrive_S
*psMntd
, char *pcSearchFile
, uint32_t *puCount
) {
1208 char pcFindCmd
[512] = {0};
1209 sprintf(pcFindCmd
, "find %s | tee /tmp/file-list.txt", psMntd
->pcMountedVol
);
1210 printf("Execute %s :\n", pcFindCmd
);
1211 iErr
= system(pcFindCmd
);
1212 printf("returned %d\n", iErr
);
1216 sprintf(pcFindCmd
, "cat /tmp/file-list.txt | grep %s | wc -l > /tmp/word-count.txt", pcSearchFile
);
1217 printf("Execute %s :\n", pcFindCmd
);
1218 iErr
= system(pcFindCmd
);
1219 printf("returned %d\n", iErr
);
1221 FILE *psCat
= fopen("/tmp/word-count.txt", "r");
1222 fscanf(psCat
, "%u", puCount
);
1228 int HFSTest_KextUnMount(MountedDrive_S
*psMntd
) {
1231 char pcUnMountCmd
[512] = {0};
1232 strcat( pcUnMountCmd
, "hdiutil detach ");
1233 strcat( pcUnMountCmd
, psMntd
->pcMountedDev
);
1234 printf("Execute %s:\n", pcUnMountCmd
);
1235 iErr
= system(pcUnMountCmd
);
1236 printf("returned %d\n", iErr
);
1241 int HFSTest_RunFsck(void) {
1243 char pcFsckCmd
[512] = {0};
1245 strcat( pcFsckCmd
, "/System/Library/Filesystems/hfs.fs/Contents/Resources/fsck_hfs -fd -D 0x22 /dev/disk");
1246 strcat( pcFsckCmd
, pcLastDevPathName
);
1248 if (pcDevNum
[0] != '\0') {
1249 strcat( pcFsckCmd
, "s" );
1250 strcat( pcFsckCmd
, pcDevNum
);
1252 printf("Execute %s:\n", pcFsckCmd
);
1254 iErr
= system( pcFsckCmd
);
1257 printf( "*** Fsck CMD failed! (%d) \n", iErr
);
1259 printf( "*** Fsck CMD succeeded!\n");
1265 int HFSTest_RestartEnv(__unused
int iFD
) {
1266 // Restart FS for following tests
1267 HFS_fsOps
.fsops_fini();
1269 int iErr
= HFS_fsOps
.fsops_init();
1270 printf("Init err [%d]\n", iErr
);
1272 printf("Can't re-init (%d).\n", iErr
);
1277 int HFSTest_FailTestOnCrashAbort(__unused
void *psTestData
, CrashAbort_E eAbort
, int iFD
, UVFSFileNode psNode
, __unused pthread_t bSyncerThread
) {
1279 printf("**** HFSTest_FailTestOnCrashAbort: eAbort (%u) \"%s\", iFD %d, psNode %p ****\n", eAbort
, ppcCrashAbortDesc
[eAbort
], iFD
, psNode
);
1281 if (eAbort
!= CRASH_ABORT_NONE
) {
1282 panic("We should never get here!\n");
1288 HFSTest_DestroyEnv( iFD
);
1293 static int HFSTest_ConfirmTestFolderExists(UVFSFileNode RootNode
) {
1296 printf("HFSTest_ConfirmTestFolderExists:\n");
1298 char pcFolderName
[256];
1299 for(unsigned u
=0; u
<5; u
++) {
1300 sprintf(pcFolderName
, "TestFolder_%u", u
);
1301 read_directory_and_search_for_name( RootNode
, pcFolderName
, &bFound
, NULL
, 0 );
1303 printf("Error: Can not find replayed dir! (%s)\n", pcFolderName
);
1306 printf("dir %s found after journal replay.\n", pcFolderName
);
1313 static int HFSTest_ConfirmTestFolderDoesntExists(UVFSFileNode RootNode
) {
1316 printf("HFSTest_ConfirmTestFolderExists:\n");
1318 read_directory_and_search_for_name( RootNode
, "TestFolder", &bFound
, NULL
, 0 );
1320 printf("dir \"TestFolder\" found.\n");
1324 printf("As expected, \"TestFolder\" was not found.\n");
1329 int HFSTest_ValidateImageOnMac(__unused TestData_S
*psTestData
, char *pcDmgFilename
, char *pcSearchItem
, bool bFindNotFind
) {
1331 MountedDrive_S sMntd
;
1333 // Validate image with fsck + Kext mount
1335 iErr
= HFSTest_KextMount(pcDmgFilename
, &sMntd
, false);
1337 printf("Can't HFSTest_KextMount(false).\n");
1342 iErr
= HFSTest_RunFsck();
1344 printf("Can't HFSTest_RunFsck.\n");
1349 iErr
= HFSTest_KextUnMount(&sMntd
);
1351 printf("Can't HFSTest_KextUnMount.\n");
1355 // Validate that we can mount
1356 iErr
= HFSTest_KextMount(pcDmgFilename
, &sMntd
, true);
1358 printf("Can't HFSTest_KextMount(true).\n");
1363 char pcSearchPath
[512] = {0};
1364 strcpy(pcSearchPath
, sMntd
.pcMountedVol
);
1365 strcat(pcSearchPath
, pcSearchItem
);
1366 printf("pcSearchPath is %s\n", pcSearchPath
);
1368 iErr
= HFSTest_KextFindAll(&sMntd
, pcSearchPath
);
1369 printf("grep returned %d.\n", iErr
);
1370 if (bFindNotFind
== false) {
1371 // Make sure string was not found on drive
1383 uint32_t uNumOfSymLinks
= 0;
1384 strcpy(pcSearchPath
, "TestSymLink_thread");
1385 iErr
= HFSTest_KextCount(&sMntd
, pcSearchPath
, &uNumOfSymLinks
);
1386 printf("*** found %u SymLinks\n", uNumOfSymLinks
);
1389 uint32_t uNumOfFiles
= 0;
1390 strcpy(pcSearchPath
, "file_Thread_");
1391 iErr
= HFSTest_KextCount(&sMntd
, pcSearchPath
, &uNumOfFiles
);
1392 printf("*** found %u files\n", uNumOfFiles
);
1396 iErr
= HFSTest_KextUnMount(&sMntd
);
1405 int HFSTest_SaveDMG(void *pvTestData
, CrashAbort_E eAbort
, int iFD
, UVFSFileNode psNode
, __unused pthread_t pSyncerThread
) {
1407 TestData_S
*psTestData
= pvTestData
;
1409 printf("**** HFSTest_SaveDMG: eAbort (%u) \"%s\", psNode %p ****\n", eAbort
, ppcCrashAbortDesc
[eAbort
], psNode
);
1413 HFSTest_DestroyEnv( iFD
);
1415 // Create a snapshot of the dmg
1416 char pcDmgFilename
[256];
1417 strcpy(pcDmgFilename
, psTestData
->bSparseImage
?TEMP_DMG_SPARSE
:TEMP_DMG
);
1419 char pcCpCmd
[512] = {0};
1420 strcat( pcCpCmd
, "cp ");
1421 strcat( pcCpCmd
, pcDmgFilename
);
1422 if (psTestData
->bSparseImage
) {
1423 strcat( pcCpCmd
, " "TEMP_DMG_BKUP_SPARSE
);
1425 strcat( pcCpCmd
, " "TEMP_DMG_BKUP
);
1427 printf("Execute %s:\n", pcCpCmd
);
1428 iErr
= system(pcCpCmd
);
1429 printf("returned %d\n", iErr
);
1437 int HFSTest_CrashAbortAtRandom(void *pvTestData
, CrashAbort_E eAbort
, int iFD
, UVFSFileNode psNode
, __unused pthread_t pSyncerThread
) {
1439 TestData_S
*psTestData
= pvTestData
;
1441 printf("**** HFSTest_CrashAbortAtRandom: eAbort (%u) \"%s\", psNode %p ****\n", eAbort
, ppcCrashAbortDesc
[eAbort
], psNode
);
1445 HFSTest_DestroyEnv( iFD
);
1447 // Create a snapshot of the crashed dmg
1448 char pcDmgFilename
[256];
1449 strcpy(pcDmgFilename
, psTestData
->bSparseImage
?TEMP_DMG_SPARSE
:TEMP_DMG
);
1451 char pcCpCmd
[512] = {0};
1452 strcat( pcCpCmd
, "cp ");
1453 strcat( pcCpCmd
, pcDmgFilename
);
1454 if (psTestData
->bSparseImage
) {
1455 strcat( pcCpCmd
, " "TEMP_DMG_BKUP_SPARSE
);
1457 strcat( pcCpCmd
, " "TEMP_DMG_BKUP
);
1459 printf("Execute %s:\n", pcCpCmd
);
1460 iErr
= system(pcCpCmd
);
1461 printf("returned %d\n", iErr
);
1466 bool bFindNotFind
= true;
1467 if (eAbort
== CRASH_ABORT_JOURNAL_AFTER_JOURNAL_HEADER
) {
1468 bFindNotFind
= true;
1470 bFindNotFind
= false;
1473 iErr
= HFSTest_ValidateImageOnMac(psTestData
, pcDmgFilename
, "/TestFolder", bFindNotFind
);
1482 int HFSTest_CrashAbortOnMkDir(void *pvTestData
, CrashAbort_E eAbort
, int iFD
, UVFSFileNode psNode
, __unused pthread_t pSyncerThread
) {
1484 TestData_S
*psTestData
= pvTestData
;
1486 printf("**** HFSTest_CrashAbortOnMkDir: eAbort (%u) \"%s\", psNode %p ****\n", eAbort
, ppcCrashAbortDesc
[eAbort
], psNode
);
1490 HFSTest_DestroyEnv( iFD
);
1492 // Create a snapshot of the crashed dmg
1493 char pcDmgFilename
[256];
1494 strcpy(pcDmgFilename
, psTestData
->bSparseImage
?TEMP_DMG_SPARSE
:TEMP_DMG
);
1496 char pcCpCmd
[512] = {0};
1497 strcat( pcCpCmd
, "cp ");
1498 strcat( pcCpCmd
, pcDmgFilename
);
1499 if (psTestData
->bSparseImage
) {
1500 strcat( pcCpCmd
, " "TEMP_DMG_BKUP_SPARSE
);
1502 strcat( pcCpCmd
, " "TEMP_DMG_BKUP
);
1504 printf("Execute %s:\n", pcCpCmd
);
1505 iErr
= system(pcCpCmd
);
1506 printf("returned %d\n", iErr
);
1511 bool bFindNotFind
= true;
1512 if (eAbort
== CRASH_ABORT_JOURNAL_AFTER_JOURNAL_HEADER
) {
1513 printf("CRASH_ABORT_JOURNAL_AFTER_JOURNAL_HEADER, expecting to find!\n");
1514 bFindNotFind
= true;
1516 bFindNotFind
= false;
1519 iErr
= HFSTest_ValidateImageOnMac(psTestData
, pcDmgFilename
, "/TestFolder", bFindNotFind
);
1525 printf("HFSTest_CrashAbortOnMkDir returns %d\n", iErr
);
1529 int HFSTest_CrashAbort(void *pvTestData
, CrashAbort_E eAbort
, int iFD
, UVFSFileNode psNode
, __unused pthread_t pSyncerThread
) {
1531 TestData_S
*psTestData
= pvTestData
;
1533 printf("**** HFSTest_CrashAbort: eAbort (%u) \"%s\", psNode %p ****\n", eAbort
, ppcCrashAbortDesc
[eAbort
], psNode
);
1537 HFSTest_DestroyEnv( iFD
);
1539 // Create a snapshot of the crashed dmg
1540 char pcDmgFilename
[256];
1541 strcpy(pcDmgFilename
, psTestData
->bSparseImage
?TEMP_DMG_SPARSE
:TEMP_DMG
);
1543 char pcCpCmd
[512] = {0};
1544 strcat( pcCpCmd
, "cp ");
1545 strcat( pcCpCmd
, pcDmgFilename
);
1546 if (psTestData
->bSparseImage
) {
1547 strcat( pcCpCmd
, " "TEMP_DMG_BKUP_SPARSE
);
1549 strcat( pcCpCmd
, " "TEMP_DMG_BKUP
);
1551 printf("Execute %s:\n", pcCpCmd
);
1552 iErr
= system(pcCpCmd
);
1553 printf("returned %d\n", iErr
);
1558 iErr
= HFSTest_ValidateImageOnMac(psTestData
, pcDmgFilename
, NULL
, false);
1569 HFSTest_ScanID( UVFSFileNode RootNode
)
1572 printf("HFSTest_ScanID\n");
1573 __block
uint64_t uScanIDFileIDArray
;
1574 __block
char* pcScanIDPath
= malloc(sizeof(char)* MAX_UTF8_NAME_LENGTH
);
1575 __block
char* pcTempPath
;
1576 __block
int iFoundRoot
= 0;
1578 //Creating the following path
1579 // /TestFolder/TestFolder2/TestFolder3/TestFolder4/TestFolder5/file.txt
1580 UVFSFileNode TestFolder
= NULL
;
1581 UVFSFileNode TestFolder2
= NULL
;
1582 UVFSFileNode TestFolder3
= NULL
;
1583 UVFSFileNode TestFolder4
= NULL
;
1584 UVFSFileNode TestFolder5
= NULL
;
1585 UVFSFileNode TestFile1
= NULL
;
1587 iErr
= CreateNewFolder( RootNode
, &TestFolder
, "TestFolder");
1588 printf("CreateNewFolder TestFolder err [%d]\n", iErr
);
1589 if (iErr
) goto exit
;
1591 iErr
= CreateNewFolder( TestFolder
, &TestFolder2
, "TestFolder2");
1592 printf("CreateNewFolder TestFolder2 err [%d]\n", iErr
);
1593 if (iErr
) goto exit
;
1595 iErr
= CreateNewFolder( TestFolder2
, &TestFolder3
, "TestFolder3");
1596 printf("CreateNewFolder TestFolder3 err [%d]\n", iErr
);
1597 if (iErr
) goto exit
;
1599 iErr
= CreateNewFolder( TestFolder3
, &TestFolder4
, "TestFolder4");
1600 printf("CreateNewFolder TestFolder4 err [%d]\n", iErr
);
1601 if (iErr
) goto exit
;
1603 iErr
= CreateNewFolder( TestFolder4
, &TestFolder5
, "TestFolder5");
1604 printf("CreateNewFolder TestFolder5 err [%d]\n", iErr
);
1605 if (iErr
) goto exit
;
1607 //Create new file with size 0
1608 iErr
= CreateNewFile(TestFolder5
, &TestFile1
, "file.txt",512);
1609 printf("Create file.txt in TestFolder5 err [%d]\n", iErr
);
1610 if (iErr
) goto exit
;
1612 LIFileAttributes_t FileAttr
;
1613 iErr
= HFS_fsOps
.fsops_getattr( TestFile1
, &FileAttr
);
1614 if (iErr
) goto exit
;
1616 HFS_fsOps
.fsops_reclaim(TestFile1
);
1618 memset(pcScanIDPath
, 0, MAX_UTF8_NAME_LENGTH
);
1619 uScanIDFileIDArray
= FileAttr
.fa_fileid
;
1623 iErr
= HFS_fsOps
.fsops_scanids(RootNode
, 0, &uScanIDFileIDArray
, 1,
1624 ^(__unused
unsigned int fileid_index
, const UVFSFileAttributes
*file_attrs
, const char *file_name
) {
1625 iFoundRoot
= (file_attrs
->fa_parentid
== file_attrs
->fa_fileid
);
1626 uScanIDFileIDArray
= file_attrs
->fa_parentid
;
1627 size_t uTmpPathSize
= strlen(pcScanIDPath
) + 1;
1628 pcTempPath
= malloc(uTmpPathSize
);
1629 strlcpy(pcTempPath
, pcScanIDPath
, uTmpPathSize
);
1630 strlcpy(pcScanIDPath
, file_name
, MAX_UTF8_NAME_LENGTH
);
1632 if (uTmpPathSize
!= 1) { //For the first time we don't want to set /
1633 strcat(pcScanIDPath
,"/");
1634 strcat(pcScanIDPath
,pcTempPath
);
1639 printf("HFS_fsOps.fsops_scanids err [%d]\n", iErr
);
1640 if (iErr
) goto exit
;
1641 } while (!iFoundRoot
);
1643 if (strcmp(pcScanIDPath
,"/TestFolder/TestFolder2/TestFolder3/TestFolder4/TestFolder5/file.txt"))
1646 printf("Found path to file [%s]\n", pcScanIDPath
);
1649 // ********************* Add Hard Links: ************************
1650 uint32_t uOriginalFileSize
= 500000;
1651 UVFSFileNode psFile
= NULL
;
1652 size_t iActuallyWrite
= 0;
1653 size_t iActuallyRead
= 0;
1654 void* pvOutBuf
= malloc(uOriginalFileSize
);
1655 void* pvInBuf
= malloc(uOriginalFileSize
);
1657 if (pvOutBuf
== NULL
|| pvInBuf
== NULL
) {
1658 printf("ERROR: HFSTest_ScanID: can't malloc (%p, %p)\n", pvOutBuf
, pvInBuf
);
1663 uint64_t* puOutBuf
= pvOutBuf
;
1664 uint64_t* puInBuf
= pvInBuf
;
1666 // Create the original file with size 500,000 Bytes
1667 iErr
= CreateNewFile( RootNode
, &psFile
, "original_file.txt", uOriginalFileSize
);
1669 printf("ERROR: CreateNewFile return %d\n", iErr
);
1674 // lets write 10,000 Bytes with 0xCD
1675 memset(pvOutBuf
, 0, uOriginalFileSize
);
1676 memset(pvInBuf
, 0, uOriginalFileSize
);
1678 memset(pvOutBuf
, 0xCD, uOriginalFileSize
);
1680 iErr
= HFS_fsOps
.fsops_write( psFile
, 0, uOriginalFileSize
, pvOutBuf
, &iActuallyWrite
);
1682 printf("ERROR: fsops_write return %d\n", iErr
);
1686 iErr
= HFS_fsOps
.fsops_read( psFile
, 0, uOriginalFileSize
, pvInBuf
, &iActuallyRead
);
1688 printf("ERROR: fsops_read return %d\n", iErr
);
1693 for ( uint64_t uIdx
=0; uIdx
<(uOriginalFileSize
/sizeof(uint64_t)); uIdx
++ ) {
1694 if (puInBuf
[uIdx
] != puOutBuf
[uIdx
] ) {
1695 printf("ERROR: puInBuf[uIdx] != puOutBuf[uIdx]\n");
1701 UVFSFileNode psDirectory
= NULL
;
1702 iErr
= CreateNewFolder(RootNode
,&psDirectory
,"dir");
1704 printf("ERROR: CreateNewFolder return %d\n", iErr
);
1707 iErr
= CreateHardLink(psFile
,RootNode
,"first_link.txt");
1709 printf("ERROR: CreateHardLink return %d\n", iErr
);
1712 iErr
= CreateHardLink(psFile
,psDirectory
,"second_link.txt");
1714 printf("ERROR: CreateHardLink return %d\n", iErr
);
1718 UVFSFileNode psFirstLink
= NULL
;
1719 iErr
= HFS_fsOps
.fsops_lookup( psDirectory
, "second_link.txt", &psFirstLink
);
1720 if (iErr
) goto exit
;
1722 iErr
= HFS_fsOps
.fsops_getattr( psFirstLink
, &FileAttr
);
1723 if (iErr
) goto exit
;
1725 uScanIDFileIDArray
= FileAttr
.fa_fileid
;
1726 memset(pcScanIDPath
, 0, MAX_UTF8_NAME_LENGTH
);
1728 HFS_fsOps
.fsops_reclaim( psFile
);
1729 HFS_fsOps
.fsops_reclaim( psFirstLink
);
1730 HFS_fsOps
.fsops_reclaim( psDirectory
);
1732 // Now run SanID on hardlinks:
1734 iErr
= HFS_fsOps
.fsops_scanids(RootNode
, 0, &uScanIDFileIDArray
, 1,
1735 ^(__unused
unsigned int fileid_index
, const UVFSFileAttributes
*file_attrs
, const char *file_name
) {
1736 iFoundRoot
= (file_attrs
->fa_parentid
== file_attrs
->fa_fileid
);
1737 uScanIDFileIDArray
= file_attrs
->fa_parentid
;
1738 size_t uTmpPathSize
= strlen(pcScanIDPath
) + 1;
1739 pcTempPath
= malloc(uTmpPathSize
);
1740 strlcpy(pcTempPath
, pcScanIDPath
, uTmpPathSize
);
1741 strlcpy(pcScanIDPath
, file_name
, MAX_UTF8_NAME_LENGTH
);
1743 if (uTmpPathSize
!= 1) { //For the first time we don't want to set /
1744 strcat(pcScanIDPath
,"/");
1745 strcat(pcScanIDPath
,pcTempPath
);
1750 printf("HFS_fsOps.fsops_scanids err [%d]\n", iErr
);
1751 if (iErr
) goto exit
;
1752 } while (!iFoundRoot
);
1754 if (strcmp(pcScanIDPath
,"/original_file.txt"))
1757 printf("Found path to file [%s]\n", pcScanIDPath
);
1764 RemoveFile(TestFolder5
,"file.txt");
1767 HFS_fsOps
.fsops_reclaim(TestFolder5
);
1768 RemoveFolder(TestFolder4
,"TestFolder5");
1771 HFS_fsOps
.fsops_reclaim(TestFolder4
);
1772 RemoveFolder(TestFolder3
,"TestFolder4");
1775 HFS_fsOps
.fsops_reclaim(TestFolder3
);
1776 RemoveFolder(TestFolder2
,"TestFolder3");
1779 HFS_fsOps
.fsops_reclaim(TestFolder2
);
1780 RemoveFolder(TestFolder
,"TestFolder2");
1783 HFS_fsOps
.fsops_reclaim(TestFolder
);
1784 RemoveFolder(RootNode
,"TestFolder");
1791 HFSTest_Create( UVFSFileNode RootNode
)
1794 printf("HFSTest_Create\n");
1796 UVFSFileNode TestFolder
= NULL
;
1797 iErr
= CreateNewFolder( RootNode
, &TestFolder
, "TestFolder");
1798 printf("CreateNewFolder err [%d]\n", iErr
);
1802 //Create new file with size 0
1803 UVFSFileNode TestFile1
= NULL
;
1804 CreateNewFile(TestFolder
, &TestFile1
, "TestFile",0);
1805 printf("Create TestFile in TestFolder err [%d]\n", iErr
);
1809 //Create new file with size 512
1810 UVFSFileNode TestFile2
= NULL
;
1811 CreateNewFile(TestFolder
, &TestFile2
, "TestFile2",512);
1812 printf("Create TestFile2 in TestFolder err [%d]\n", iErr
);
1816 uint32_t uEntrySize
= sizeof(UVFSDirEntryAttr
) + MAX_UTF8_NAME_LENGTH
;
1817 UVFSDirEntryAttr
*psReadDirTestsData
= malloc(2*uEntrySize
);
1818 if (psReadDirTestsData
== NULL
)
1821 UVFSDirEntryAttr
*psCurrentReadDirTestsData
= psReadDirTestsData
;
1822 SetExpectedAttr("TestFile", UVFS_FA_TYPE_FILE
, psCurrentReadDirTestsData
);
1823 iErr
= HFS_fsOps
.fsops_getattr( TestFile1
, &psCurrentReadDirTestsData
->dea_attrs
);
1824 psCurrentReadDirTestsData
= (UVFSDirEntryAttr
*) ((void*) psCurrentReadDirTestsData
+ uEntrySize
);
1825 SetExpectedAttr("TestFile2", UVFS_FA_TYPE_FILE
, psCurrentReadDirTestsData
);
1826 iErr
= HFS_fsOps
.fsops_getattr( TestFile2
, &psCurrentReadDirTestsData
->dea_attrs
);
1829 // {.pcTestName = "TestFile", .uTyppe = UVFS_FA_TYPE_FILE, .uSize = 0, .uNlink = 1, .uAllocatedSize = 0},
1830 // {.pcTestName = "TestFile2", .uTyppe = UVFS_FA_TYPE_FILE, .uSize = 512, .uNlink = 1, .uAllocatedSize = 4096},
1833 iErr
= ReadDirAttr(TestFolder
, psReadDirTestsData
, 2);
1834 free(psReadDirTestsData
);
1835 printf("ReadDirAttr err [%d]\n", iErr
);
1840 iErr
= RemoveFile(TestFolder
,"TestFile");
1841 printf("Remove File TestFile from TestFolder err [%d]\n", iErr
);
1846 iErr
= RemoveFile(TestFolder
,"TestFile2");
1847 printf("Remove File TestFile2 from TestFolder err [%d]\n", iErr
);
1851 // Remove TestFolder
1852 iErr
= RemoveFolder(RootNode
,"TestFolder");
1853 printf("Remove Folder TestFolder from Root err [%d]\n", iErr
);
1858 HFS_fsOps
.fsops_reclaim(TestFolder
);
1859 HFS_fsOps
.fsops_reclaim(TestFile1
);
1860 HFS_fsOps
.fsops_reclaim(TestFile2
);
1864 // This function tests the system behavior when deleting a very large defragmented file,
1865 // which will cause the creation of a very large journal transaction and lots of BT buffers
1866 static int HFSTest_DeleteAHugeDefragmentedFile_wJournal(UVFSFileNode RootNode
) {
1867 #define DHF_NUM_OF_FILES_TO_CREATE 1000
1868 #define DHF_HUGE_FILE_SIZE (15000000000ULL) // 15GBytes
1869 #define DHF_SMALL_FILENAME "SmallFile"
1870 #define DHF_HUGE_FILENAME "HugeFile"
1874 // Create many small files
1875 char pcName
[100] = {0};
1876 UVFSFileNode psNode
;
1877 for ( int i
=0; i
<DHF_NUM_OF_FILES_TO_CREATE
; i
++ ) {
1878 sprintf(pcName
, "%s_%u.txt", DHF_SMALL_FILENAME
, i
);
1879 printf("Creating file %s\n", pcName
);
1880 if ( (iErr
= CreateNewFile(RootNode
, &psNode
, pcName
, 100)) != 0 ) {
1881 printf("Failed to create file [%s]\n", pcName
);
1884 HFS_fsOps
.fsops_reclaim(psNode
);
1887 // delete every other file
1888 for ( int i
=0; i
<DHF_NUM_OF_FILES_TO_CREATE
; i
+=2 ) {
1889 sprintf(pcName
, "%s_%u.txt", DHF_SMALL_FILENAME
, i
);
1890 printf("Removing file %s\n", pcName
);
1891 if ( (iErr
= RemoveFile(RootNode
, pcName
)) != 0 ) {
1892 printf("Failed to remove file [%s]", pcName
);
1897 // Create a huge file
1898 sprintf(pcName
, "%s.txt", DHF_HUGE_FILENAME
);
1899 printf("Creating huge file %s\n", pcName
);
1900 if ( (iErr
= CreateNewFile(RootNode
, &psNode
, pcName
, DHF_HUGE_FILE_SIZE
)) != 0 ) {
1901 printf("Failed to create file [%s]\n", pcName
);
1904 HFS_fsOps
.fsops_reclaim(psNode
);
1906 // Delete the huge defragmented file
1907 sprintf(pcName
, "%s.txt", DHF_HUGE_FILENAME
);;
1908 printf("Removing file %s\n", pcName
);
1909 if ( (iErr
= RemoveFile(RootNode
, pcName
)) != 0 ) {
1910 printf("Failed to remove file [%s]", pcName
);
1919 static void *ReadWriteThread(void *pvArgs
) {
1922 RWThreadData_S
*psThrdData
= pvArgs
;
1923 UVFSFileNode psRootNode
= psThrdData
->psRootNode
;
1924 char pcName
[100] = {0};
1925 char *pcFilenameFormat
= "file_Thread_%u_OpCnt_%u_FileNum_%u_Len_%u.txt";
1927 for(uint32_t uOpCnt
=0; uOpCnt
<MTRW_NUM_OF_OPERATIONS
; uOpCnt
++) {
1930 for(uint32_t uNumOfFiles
=0; uNumOfFiles
<psThrdData
->uNumOfFiles
; uNumOfFiles
++) {
1932 UVFSFileNode psNode
;
1933 uint64_t uLen
= psThrdData
->uFileSize
* uNumOfFiles
;
1934 sprintf(pcName
, pcFilenameFormat
, psThrdData
->uThreadNum
, uOpCnt
, uNumOfFiles
, uLen
);
1935 printf("Creating file %s\n", pcName
);
1936 iErr
= CreateNewFile(psRootNode
, &psNode
, pcName
, uLen
);
1938 printf("Failed creating file %s with iErr %d.\n", pcName
,iErr
);
1941 HFS_fsOps
.fsops_reclaim(psNode
);
1945 UVFSFileNode
*pOutNode
= malloc(sizeof(UVFSFileNode
) * psThrdData
->uNumOfSymLinks
);
1946 uint32_t uSymLinkMode
= UVFS_FA_MODE_USR(UVFS_FA_MODE_RWX
) | UVFS_FA_MODE_GRP(UVFS_FA_MODE_R
) | UVFS_FA_MODE_OTH(UVFS_FA_MODE_R
| UVFS_FA_MODE_X
);
1947 for(uint32_t uNumOfSymLinks
=0; uNumOfSymLinks
<psThrdData
->uNumOfSymLinks
; uNumOfSymLinks
++) {
1950 char pcSymLinkName
[256] = {0};
1951 sprintf(pcSymLinkName
, "TestSymLink_thread_%u_op_%u_symlink_%u", psThrdData
->uThreadNum
, uOpCnt
, uNumOfSymLinks
);
1952 uint32_t uSymLinkSize
= psThrdData
->uSymLinkSize
;
1953 char *pcSymLinkContent
= malloc(uSymLinkSize
);
1954 memset(pcSymLinkContent
, 0, uSymLinkSize
);
1955 uint32_t uStampLen
= sprintf(pcSymLinkContent
, "/just/to/check/that/symlink/works/properly/thread/%u/op/%u/symlink_%u",psThrdData
->uThreadNum
, uOpCnt
, uNumOfSymLinks
);
1956 assert(uSymLinkSize
>= uStampLen
);
1957 for(uint32_t uStampCount
=1; uSymLinkSize
>(uStampCount
+1)*uStampLen
+1; uStampCount
++) {
1958 memcpy(pcSymLinkContent
+ uStampCount
*uStampLen
, pcSymLinkContent
, uStampLen
);
1960 assert(strlen(pcSymLinkContent
) + 1 <= uSymLinkSize
);
1962 UVFSFileAttributes sAttr
= {0};
1963 sAttr
.fa_validmask
= UVFS_FA_VALID_MODE
;
1964 sAttr
.fa_type
= UVFS_FA_TYPE_SYMLINK
;
1965 sAttr
.fa_mode
= uSymLinkMode
;
1967 pOutNode
[uNumOfSymLinks
] = NULL
;
1968 printf("Creating Symlink %s\n", pcSymLinkName
);
1969 iErr
= HFS_fsOps
.fsops_symlink(psRootNode
, pcSymLinkName
, pcSymLinkContent
, &sAttr
, &pOutNode
[uNumOfSymLinks
] );
1971 printf( "fsops_symlink failed with eror code : %d\n", iErr
);
1974 free(pcSymLinkContent
);
1977 // Verify Symlink content
1978 for(uint32_t uNumOfSymLinks
=0; uNumOfSymLinks
<psThrdData
->uNumOfSymLinks
; uNumOfSymLinks
++) {
1980 uint32_t uSymLinkSize
= psThrdData
->uSymLinkSize
;
1981 char pcSymLinkName
[256] = {0};
1982 sprintf(pcSymLinkName
, "TestSymLink_thread_%u_op_%u_symlink_%u", psThrdData
->uThreadNum
, uOpCnt
, uNumOfSymLinks
);
1983 char *pcSymLinkReadContent
= malloc(uSymLinkSize
);
1984 memset(pcSymLinkReadContent
, 0, uSymLinkSize
);
1985 size_t iActuallyRead
;
1987 UVFSFileAttributes sOutAttr
= {0};
1989 printf("Reading Symlink %s\n", pcSymLinkName
);
1990 iErr
= HFS_fsOps
.fsops_readlink( pOutNode
[uNumOfSymLinks
], pcSymLinkReadContent
, uSymLinkSize
, &iActuallyRead
, &sOutAttr
);
1993 printf( "fsops_readlink failed with eror code : %d\n", iErr
);
1997 char *pcSymLinkContent
= malloc(uSymLinkSize
);
1998 memset(pcSymLinkContent
, 0, uSymLinkSize
);
1999 uint32_t uStampLen
= sprintf(pcSymLinkContent
, "/just/to/check/that/symlink/works/properly/thread/%u/op/%u/symlink_%u",psThrdData
->uThreadNum
, uOpCnt
, uNumOfSymLinks
);
2000 assert(uSymLinkSize
>= uStampLen
);
2001 for(uint32_t uStampCount
=1; uSymLinkSize
>(uStampCount
+1)*uStampLen
+1; uStampCount
++) {
2002 memcpy(pcSymLinkContent
+ uStampCount
*uStampLen
, pcSymLinkContent
, uStampLen
);
2005 if ( memcmp( pcSymLinkContent
, pcSymLinkReadContent
, uSymLinkSize
) != 0 ) {
2006 printf( "Read bad symlink content\n" );
2011 if ( sOutAttr
.fa_mode
!= uSymLinkMode
) {
2012 printf( "Mode mismatch [%d != %d]\n", sOutAttr
.fa_mode
, uSymLinkMode
);
2017 if ( sOutAttr
.fa_type
!= UVFS_FA_TYPE_SYMLINK
) {
2018 printf( "Type mismatch\n" );
2023 HFS_fsOps
.fsops_reclaim( pOutNode
[uNumOfSymLinks
] );
2024 free(pcSymLinkContent
);
2025 free(pcSymLinkReadContent
);
2030 for(uint32_t uNumOfFiles
=0; uNumOfFiles
<psThrdData
->uNumOfFiles
; uNumOfFiles
++) {
2031 uint64_t uLen
= psThrdData
->uFileSize
* uNumOfFiles
;
2032 sprintf(pcName
, pcFilenameFormat
, psThrdData
->uThreadNum
, uOpCnt
, uNumOfFiles
, uLen
);
2033 printf("Removing file %s\n", pcName
);
2034 iErr
= RemoveFile(psRootNode
, pcName
);
2036 printf("Failed deleting file %s with iErr %d.\n", pcName
, iErr
);
2042 for(uint32_t uNumOfSymLinks
=0; uNumOfSymLinks
<psThrdData
->uNumOfSymLinks
; uNumOfSymLinks
++) {
2044 char pcSymLinkName
[256] = {0};
2045 sprintf(pcSymLinkName
, "TestSymLink_thread_%u_op_%u_symlink_%u", psThrdData
->uThreadNum
, uOpCnt
, uNumOfSymLinks
);
2047 printf("Deleting Symlink %s\n", pcSymLinkName
);
2048 iErr
= HFS_fsOps
.fsops_remove(psRootNode
, pcSymLinkName
, NULL
);
2050 printf( "Failed to remove symlink %d\n", iErr
);
2056 psThrdData
->iRetVal
= iErr
;
2061 static int MultiThreadedRW_wJournal_RandomCrash(UVFSFileNode psRootNode
) {
2064 pthread_attr_t sAttr
;
2065 pthread_attr_setdetachstate(&sAttr
, PTHREAD_CREATE_JOINABLE
);
2066 pthread_attr_init(&sAttr
);
2067 pthread_t psExecThread
[MTRW_NUM_OF_THREADS
];
2068 RWThreadData_S pcThreadData
[MTRW_NUM_OF_THREADS
] = {{0}};
2069 for(uint32_t u
= 0; u
< MTRW_NUM_OF_THREADS
; u
++) {
2070 pcThreadData
[u
].uThreadNum
= u
;
2071 pcThreadData
[u
].psRootNode
= psRootNode
;
2072 pcThreadData
[u
].uNumOfFiles
= MTRW_NUM_OF_FILES
*(u
+1);
2073 pcThreadData
[u
].uFileSize
= MTRW_FILE_SIZE
;
2074 pcThreadData
[u
].uNumOfSymLinks
= MTRW_NUM_OF_SYMLINKS
*(u
+1);
2075 pcThreadData
[u
].uSymLinkSize
= MTRW_SYMLINK_SIZE
;
2077 iErr
= pthread_create(&psExecThread
[u
], &sAttr
, ReadWriteThread
, &pcThreadData
[u
]);
2079 printf("can't pthread_create\n");
2083 pthread_attr_destroy(&sAttr
);
2086 srand((unsigned) time(&sTime
));
2087 uint32_t uRandTime
= 0;
2088 if (guSyncerPeriod
) {
2089 uRandTime
= rand() % (guSyncerPeriod
* 150);
2091 uRandTime
= rand() % (15000);
2093 printf("******* uRandTime is %u mS ******\n", uRandTime
);
2095 uint32_t uAbortTime
= uRandTime
; // mSec
2096 usleep(uAbortTime
* 1000);
2098 printf("******* now: close(giFD) **************\n");
2100 for(uint32_t u
= 0; u
< MTRW_NUM_OF_THREADS
; u
++) {
2101 iErr
= pthread_join(psExecThread
[u
], NULL
);
2103 printf("can't pthread_join\n");
2106 iErr
= pcThreadData
[u
].iRetVal
;
2108 printf("Thread %u return error %d\n", u
, iErr
);
2118 static int HFSTest_MultiThreadedRW_wJournal(UVFSFileNode psRootNode
) {
2122 pthread_attr_t sAttr
;
2123 pthread_attr_setdetachstate(&sAttr
, PTHREAD_CREATE_JOINABLE
);
2124 pthread_attr_init(&sAttr
);
2125 pthread_t psExecThread
[MTRW_NUM_OF_THREADS
];
2126 RWThreadData_S pcThreadData
[MTRW_NUM_OF_THREADS
] = {{0}};
2127 for(uint32_t u
= 0; u
< MTRW_NUM_OF_THREADS
; u
++) {
2128 pcThreadData
[u
].uThreadNum
= u
;
2129 pcThreadData
[u
].psRootNode
= psRootNode
;
2130 pcThreadData
[u
].uNumOfFiles
= MTRW_NUM_OF_FILES
*(u
+1);
2131 pcThreadData
[u
].uFileSize
= MTRW_FILE_SIZE
;
2132 pcThreadData
[u
].uNumOfSymLinks
= MTRW_NUM_OF_SYMLINKS
;
2133 pcThreadData
[u
].uSymLinkSize
= MTRW_SYMLINK_SIZE
/3;
2135 iErr
= pthread_create(&psExecThread
[u
], &sAttr
, ReadWriteThread
, &pcThreadData
[u
]);
2137 printf("can't pthread_create\n");
2141 pthread_attr_destroy(&sAttr
);
2143 for(uint32_t u
= 0; u
< MTRW_NUM_OF_THREADS
; u
++) {
2144 iErr
= pthread_join(psExecThread
[u
], NULL
);
2146 printf("can't pthread_join\n");
2149 iErr
= pcThreadData
[u
].iRetVal
;
2151 printf("Thread %u return error %d\n", u
, iErr
);
2160 HFSTest_Create1000Files( UVFSFileNode RootNode
)
2162 #define CREATE_NUM_OF_FILES (1000)
2163 #define FILE_NAME "Iamjustasimplefile_%d"
2167 char pcName
[100] = {0};
2168 UVFSFileNode psNode
;
2169 for ( int i
=0; i
<CREATE_NUM_OF_FILES
; i
++ )
2171 sprintf(pcName
, FILE_NAME
, i
);
2172 printf("Creating file %s\n", pcName
);
2173 if ( (iErr
= CreateNewFile(RootNode
, &psNode
, pcName
, 0)) != 0 )
2175 printf("Failed to create file [%s]\n", pcName
);
2178 HFS_fsOps
.fsops_reclaim(psNode
);
2181 for ( int i
=0; i
<CREATE_NUM_OF_FILES
; i
++ )
2183 sprintf(pcName
, FILE_NAME
, i
);
2184 printf("Removing file %s\n", pcName
);
2185 if ( (iErr
= RemoveFile(RootNode
, pcName
)) != 0 )
2187 printf("Failed to remove file [%s]", pcName
);
2197 HFSTest_Rename( UVFSFileNode RootNode
)
2201 printf("HFSTest_Rename\n");
2203 UVFSFileNode TestFolder
= NULL
;
2204 iErr
= CreateNewFolder( RootNode
, &TestFolder
, "TestFolder");
2205 printf("CreateNewFolder err [%d]\n", iErr
);
2209 //Create new file with size 0
2210 UVFSFileNode TestFile1
= NULL
;
2211 CreateNewFile(TestFolder
, &TestFile1
, "TestFile",0);
2212 printf("Create TestFile in TestFolder err [%d]\n", iErr
);
2216 //Create new file with size 512
2217 UVFSFileNode TestFile2
= NULL
;
2218 CreateNewFile(TestFolder
, &TestFile2
, "TestFile2",512);
2219 printf("Create TestFile2 in TestFolder err [%d]\n", iErr
);
2224 uint32_t uEntrySize
= sizeof(UVFSDirEntryAttr
) + MAX_UTF8_NAME_LENGTH
;
2225 UVFSDirEntryAttr
*psReadDirTestsData
= malloc(2*uEntrySize
);
2226 if (psReadDirTestsData
== NULL
)
2229 UVFSDirEntryAttr
*psCurrentReadDirTestsData
= psReadDirTestsData
;
2230 SetExpectedAttr("TestFile", UVFS_FA_TYPE_FILE
, psCurrentReadDirTestsData
);
2231 iErr
= HFS_fsOps
.fsops_getattr( TestFile1
, &psCurrentReadDirTestsData
->dea_attrs
);
2232 psCurrentReadDirTestsData
= (UVFSDirEntryAttr
*) ((void*) psCurrentReadDirTestsData
+ uEntrySize
);
2233 SetExpectedAttr("TestFile2", UVFS_FA_TYPE_FILE
, psCurrentReadDirTestsData
);
2234 iErr
= HFS_fsOps
.fsops_getattr( TestFile2
, &psCurrentReadDirTestsData
->dea_attrs
);
2236 iErr
= ReadDirAttr(TestFolder
, psReadDirTestsData
, 2);
2237 free(psReadDirTestsData
);
2238 printf("ReadDirAttr err [%d]\n", iErr
);
2243 iErr
= RenameFile(TestFolder
, TestFile1
, "TestFile", TestFolder
, NULL
, "TestFile3");
2244 printf("Rename TestFile to TestFile3 in same dir err [%d]\n", iErr
);
2248 iErr
= RenameFile(TestFolder
, TestFile2
, "TestFile2", RootNode
, NULL
, "TestFile4");
2249 printf("Rename TestFile2 to TestFile4 in diff Dir err [%d]\n", iErr
);
2253 iErr
= RenameFile(RootNode
, TestFolder
, "TestFolder", RootNode
, NULL
, "TestFolder5");
2254 printf("Rename Dir TestFolder to TestFolder5 err [%d]\n", iErr
);
2258 iErr
= RenameFile(TestFolder
, TestFile1
, "TestFile3", RootNode
, TestFile2
, "TestFile4");
2259 printf("Rename TestFile3 to TestFile4 in diff Dir err [%d]\n", iErr
);
2265 iErr
= RemoveFile(RootNode
,"TestFile4");
2266 printf("Remove File TestFile2 from TestFolder err [%d]\n", iErr
);
2270 // Remove TestFolder
2271 iErr
= RemoveFolder(RootNode
,"TestFolder5");
2272 printf("Remove Folder TestFolder from Root err [%d]\n", iErr
);
2277 HFS_fsOps
.fsops_reclaim(TestFolder
);
2278 HFS_fsOps
.fsops_reclaim(TestFile1
);
2279 HFS_fsOps
.fsops_reclaim(TestFile2
);
2283 static int ScanDir(UVFSFileNode UVFSFolderNode
, char** contain_str_array
, char** end_with_str_array
, struct timespec mTime
)
2287 scandir_matching_request_t sMatchingCriteria
= {0};
2288 UVFSFileAttributes smr_attribute_filter
= {0};
2289 scandir_matching_reply_t sMatchingResult
= {0};
2290 void* pvAttrBuf
= malloc(sizeof(UVFSDirEntryAttr
) + MAX_UTF8_NAME_LENGTH
*sizeof(char));
2291 sMatchingResult
.smr_entry
= pvAttrBuf
;
2293 sMatchingCriteria
.smr_filename_contains
= contain_str_array
;
2294 sMatchingCriteria
.smr_filename_ends_with
= end_with_str_array
;
2295 sMatchingCriteria
.smr_attribute_filter
= &smr_attribute_filter
;
2297 if (mTime
.tv_nsec
!= 0 || mTime
.tv_sec
!= 0 )
2299 sMatchingCriteria
.smr_attribute_filter
->fa_validmask
|= UVFS_FA_VALID_MTIME
;
2300 sMatchingCriteria
.smr_attribute_filter
->fa_mtime
= mTime
;
2303 bool bConRead
= true;
2307 err
= HFS_fsOps
.fsops_scandir (UVFSFolderNode
, &sMatchingCriteria
, &sMatchingResult
);
2308 if ( err
!= 0 || ( sMatchingResult
.smr_entry
->dea_nextcookie
== UVFS_DIRCOOKIE_EOF
&& sMatchingResult
.smr_result_type
== 0 ) )
2314 if ( sMatchingResult
.smr_entry
->dea_nextcookie
== UVFS_DIRCOOKIE_EOF
)
2318 printf("SearchDir Returned with status %d, FileName = [%s], M-Time sec:[%ld] nsec:[%ld].\n", sMatchingResult
.smr_result_type
, UVFS_DIRENTRYATTR_NAMEPTR(sMatchingResult
.smr_entry
),sMatchingResult
.smr_entry
->dea_attrs
.fa_mtime
.tv_sec
,sMatchingResult
.smr_entry
->dea_attrs
.fa_mtime
.tv_nsec
);
2320 sMatchingCriteria
.smr_start_cookie
= sMatchingResult
.smr_entry
->dea_nextcookie
;
2321 sMatchingCriteria
.smr_verifier
= sMatchingResult
.smr_verifier
;
2331 static int HFSTest_Corrupted2ndDiskImage(__unused UVFSFileNode RootNode
)
2334 printf("HFSTest_Corrupted2ndDiskImage:\n");
2336 UVFSFileNode TestFolder1
= NULL
;
2337 iErr
= CreateNewFolder( RootNode
, &TestFolder1
, "StamFolder");
2338 printf("CreateNewFolder err [%d]\n", iErr
);
2339 if (iErr
) goto exit
;
2341 HFS_fsOps
.fsops_reclaim(TestFolder1
);
2347 static int HFSTest_ScanDir(UVFSFileNode RootNode
)
2350 UVFSFileNode TestFolder1
= NULL
;
2351 UVFSFileNode TestFolder2
= NULL
;
2352 UVFSFileNode TestFile1
= NULL
;
2354 iErr
= CreateNewFolder( RootNode
, &TestFolder1
, "D2");
2355 printf("CreateNewFolder err [%d]\n", iErr
);
2356 if (iErr
) goto exit
;
2358 iErr
= CreateNewFolder( RootNode
, &TestFolder2
, "ÖÖ");
2359 printf("CreateNewFolder err [%d]\n", iErr
);
2360 if (iErr
) goto exit
;
2362 //Create new file with size 0
2363 iErr
= CreateNewFile(RootNode
, &TestFile1
, "F🤪2",0);
2364 printf("Create TestFile in TestFolder err [%d]\n", iErr
);
2365 if (iErr
) goto exit
;
2367 UVFSFileAttributes sOutAttrs
;
2368 iErr
= HFS_fsOps
.fsops_getattr(TestFile1
, &sOutAttrs
);
2369 printf("fsops_getattr F🤪2 err [%d]\n",iErr
);
2370 if (iErr
) goto exit
;
2372 struct timespec mTime
= {0};
2373 mTime
.tv_nsec
= sOutAttrs
.fa_mtime
.tv_nsec
;
2374 mTime
.tv_sec
= sOutAttrs
.fa_mtime
.tv_sec
;
2376 char* name_contains_array
[5] = {0};
2377 char* name_end_with_array
[5] = {0};
2378 char Smile
[5] = "🤪";
2379 char ContainLetter
[2] = "d";
2380 char EndsWithLetter
[2] = "2";
2381 char SpecialChar
[3] = "ö";
2383 name_contains_array
[0] = (char*) Smile
;
2384 name_contains_array
[1] = (char*) ContainLetter
;
2385 name_contains_array
[2] = (char*) SpecialChar
;
2386 name_contains_array
[3] = NULL
;
2388 name_end_with_array
[0] = (char*) EndsWithLetter
;
2389 name_end_with_array
[1] = (char*) SpecialChar
;
2390 name_end_with_array
[2] = NULL
;
2392 iErr
= ScanDir(RootNode
, (char**) &name_contains_array
, (char**) &name_end_with_array
, mTime
);
2393 printf("ScanDir err [%d]\n",iErr
);
2396 HFS_fsOps
.fsops_reclaim(TestFolder1
);
2397 HFS_fsOps
.fsops_reclaim(TestFolder2
);
2398 HFS_fsOps
.fsops_reclaim(TestFile1
);
2401 iErr
= RemoveFile(RootNode
,"F🤪2");
2402 printf("Remove File F🤪2 from TestFolder err [%d]\n", iErr
);
2403 if (iErr
) goto exit
;
2405 iErr
= RemoveFolder(RootNode
,"D2");
2406 printf("Remove Folder D1 from Root err [%d]\n", iErr
);
2407 if (iErr
) goto exit
;
2409 iErr
= RemoveFolder(RootNode
,"ÖÖ");
2410 printf("Remove Folder ÖÖ from Root err [%d]\n", iErr
);
2411 if (iErr
) goto exit
;
2416 static int HFSTest_RootFillUp( UVFSFileNode RootNode
) {
2417 #define ROOT_FILL_UP_NUM_OF_FOLDERS 512
2418 #define ROOT_FILL_UP_NUM_OF_SYMLINKS 512
2419 UVFSFileNode pTestFolder
[ROOT_FILL_UP_NUM_OF_FOLDERS
] = {NULL
};
2425 printf("HFSTest_RootFillUp\n");
2428 for(u
=0; u
<ROOT_FILL_UP_NUM_OF_FOLDERS
; u
++) {
2430 char pcFolderName
[256] = {0};
2431 sprintf(pcFolderName
, "TestFolder_%d", u
);
2433 printf("Creating folder %s.\n", pcFolderName
);
2434 iErr
= CreateNewFolder( RootNode
, &pTestFolder
[u
], pcFolderName
);
2435 //printf("iErr [%d]\n", iErr);
2437 printf("Error: Creating folder %s. iErr [%d]\n", pcFolderName
, iErr
);
2442 // Validate folders exist
2443 for(u
=0; u
<ROOT_FILL_UP_NUM_OF_FOLDERS
; u
++) {
2445 char pcFolderName
[256] = {0};
2446 sprintf(pcFolderName
, "TestFolder_%d", u
);
2449 read_directory_and_search_for_name( RootNode
, pcFolderName
, &bFound
, NULL
, 0);
2451 printf("Error: %s wasn't found in Root.\n", pcFolderName
);
2454 printf("%s was found in Root.\n", pcFolderName
);
2459 for(u
=0; u
<ROOT_FILL_UP_NUM_OF_FOLDERS
; u
++) {
2461 char pcFolderName
[256] = {0};
2462 sprintf(pcFolderName
, "TestFolder_%d", u
);
2464 HFS_fsOps
.fsops_reclaim(pTestFolder
[u
]);
2465 iErr
= RemoveFolder(RootNode
, pcFolderName
);
2466 printf("Remove Folder %s from Root err [%d]\n", pcFolderName
, iErr
);
2472 // Validate folders have been removed
2473 for(u
=0; u
<ROOT_FILL_UP_NUM_OF_FOLDERS
; u
++) {
2475 char pcFolderName
[256] = {0};
2476 sprintf(pcFolderName
, "TestFolder_%d", u
);
2479 read_directory_and_search_for_name( RootNode
, pcFolderName
, &bFound
, NULL
, 0 );
2481 printf("Found deleted dir! (%s)", pcFolderName
);
2484 printf(" Folder %s has been removed successfully.\n", pcFolderName
);
2490 UVFSFileNode pOutNode
[ROOT_FILL_UP_NUM_OF_SYMLINKS
] = {NULL
};
2491 uint32_t uSymLinkMode
= UVFS_FA_MODE_USR(UVFS_FA_MODE_RWX
) | UVFS_FA_MODE_GRP(UVFS_FA_MODE_R
) | UVFS_FA_MODE_OTH(UVFS_FA_MODE_R
| UVFS_FA_MODE_X
);
2492 for(u
=0; u
<ROOT_FILL_UP_NUM_OF_SYMLINKS
; u
++) {
2494 char pcSymLinkName
[256] = {0};
2495 sprintf(pcSymLinkName
, "TestSymLink_%d", u
);
2496 char pcSymLinkContent
[256] = {0};
2497 sprintf(pcSymLinkContent
, "/just/for/check/that/symlink/work/properly_%d", u
);
2498 UVFSFileAttributes sAttr
= {0};
2499 sAttr
.fa_validmask
= UVFS_FA_VALID_MODE
;
2500 sAttr
.fa_type
= UVFS_FA_TYPE_SYMLINK
;
2501 sAttr
.fa_mode
= uSymLinkMode
;
2503 iErr
= HFS_fsOps
.fsops_symlink( RootNode
, pcSymLinkName
, pcSymLinkContent
, &sAttr
, &pOutNode
[u
] );
2505 printf( "fsops_symlink failed with eror code : %d\n", iErr
);
2509 //HFS_fsOps.fsops_reclaim( pOutNode[u] );
2513 // Verify Symlink content
2514 for(u
=0; u
<ROOT_FILL_UP_NUM_OF_SYMLINKS
; u
++) {
2516 char pcSymLinkName
[256] = {0};
2517 sprintf(pcSymLinkName
, "TestSymLink_%d", u
);
2518 char pcSymLinkReadContent
[256] = {0};
2519 size_t iActuallyRead
;
2521 //UVFSFileNode SymLinkNode = NULL;
2522 //iErr = HFS_fsOps.fsops_lookup( RootNode, pcSymLinkName, &SymLinkNode );
2523 //printf("Symlink (%s) Lookup err [%d]\n", pcSymLinkName, iErr);
2527 UVFSFileAttributes sOutAttr
= {0};
2529 iErr
= HFS_fsOps
.fsops_readlink( pOutNode
[u
], pcSymLinkReadContent
, sizeof(pcSymLinkReadContent
), &iActuallyRead
, &sOutAttr
);
2530 //iErr = HFS_fsOps.fsops_readlink( SymLinkNode, pcSymLinkReadContent, sizeof(pcSymLinkReadContent), &iActuallyRead, &sOutAttr );
2532 printf( "fsops_readlink failed with eror code : %d\n", iErr
);
2536 char pcSymLinkContent
[256] = {0};
2537 sprintf(pcSymLinkContent
, "/just/for/check/that/symlink/work/properly_%d", u
);
2539 if ( strcmp( pcSymLinkContent
, pcSymLinkReadContent
) != 0 ) {
2540 printf( "Read bad symlink content\n" );
2545 if ( sOutAttr
.fa_mode
!= uSymLinkMode
) {
2546 printf( "Mode mismatch [%d != %d]\n", sOutAttr
.fa_mode
, uSymLinkMode
);
2551 if ( sOutAttr
.fa_type
!= UVFS_FA_TYPE_SYMLINK
) {
2552 printf( "Type mismatch\n" );
2557 HFS_fsOps
.fsops_reclaim( pOutNode
[u
] );
2558 //HFS_fsOps.fsops_reclaim( SymLinkNode );
2562 for(u
=0; u
<ROOT_FILL_UP_NUM_OF_SYMLINKS
; u
++) {
2564 char pcSymLinkName
[256] = {0};
2565 sprintf(pcSymLinkName
, "TestSymLink_%d", u
);
2567 iErr
= HFS_fsOps
.fsops_remove( RootNode
, pcSymLinkName
, NULL
);
2569 printf( "Failed to remove symlink %d\n", iErr
);
2574 read_directory_and_search_for_name( RootNode
, pcSymLinkName
, &bFound
, NULL
, 0 );
2576 printf( "Failed to remove symlink\n");
2585 static int ReadUnMountBit(UVFSFileNode psRootNode
, uint32_t *puUnMountBit
) {
2588 char pcVolumeHeader
[512];
2589 uint64_t uActuallyRead
= 0;
2590 iErr
= raw_readwrite_read_mount(psRootNode
, 2, 512, pcVolumeHeader
, 512, &uActuallyRead
, NULL
);
2592 printf("Failed to read volume header\n");
2596 uint32_t uVolHdrAttributesBigEndian
= *(uint32_t*)(pcVolumeHeader
+4);
2597 uint32_t uVolHdrAttributes
= OSSwapBigToHostInt32(uVolHdrAttributesBigEndian
);
2598 printf("uVolHdrAttributes 0x%x\n", uVolHdrAttributes
);
2600 uint32_t uUnMountBit
= (uVolHdrAttributes
& 0x00000100)?1:0;
2601 printf("uUnMountBit %u\n", uUnMountBit
);
2603 *puUnMountBit
= uUnMountBit
;
2609 static int HFSTest_ValidateUnmount_wJournal( UVFSFileNode psRootNode
) {
2612 printf("HFSTest_ValidateUnmount_wJournal\n");
2614 UVFSFileNode psTestFolder
= NULL
;
2615 iErr
= CreateNewFolder( psRootNode
, &psTestFolder
, "TestFolder");
2616 printf("CreateNewFolder err [%d]\n", iErr
);
2620 HFS_fsOps
.fsops_reclaim( psTestFolder
);
2622 // Read volume header & validate unmount is set (journaled data is still in cache)
2623 uint32_t uUnMountBit
;
2624 if (ReadUnMountBit(psRootNode
, &uUnMountBit
)) {
2629 printf("uUnMountBit is cleared though it should be set\n");
2635 HFS_fsOps
.fsops_sync(psRootNode
);
2637 // Read volume header & validate unmount is set
2638 if (ReadUnMountBit(psRootNode
, &uUnMountBit
)) {
2642 printf("uUnMountBit is cleared though it should be set\n");
2651 static int HFSTest_ValidateUnmount( UVFSFileNode psRootNode
) {
2653 uint32_t uUnMountBit
;
2655 printf("HFSTest_ValidateUnmount\n");
2657 UVFSFileNode psTestFolder
= NULL
;
2658 iErr
= CreateNewFolder( psRootNode
, &psTestFolder
, "TestFolder_1");
2659 printf("CreateNewFolder err [%d]\n", iErr
);
2663 HFS_fsOps
.fsops_reclaim( psTestFolder
);
2665 // Read volume header & validate unmount is cleared
2666 if (ReadUnMountBit(psRootNode
, &uUnMountBit
)) {
2671 printf("uUnMountBit is set though it should be cleared\n");
2677 HFS_fsOps
.fsops_sync(psRootNode
);
2679 // Read volume header & validate unmount is set
2680 if (ReadUnMountBit(psRootNode
, &uUnMountBit
)) {
2684 printf("uUnMountBit is cleared though it should be set\n");
2689 iErr
= CreateNewFolder( psRootNode
, &psTestFolder
, "TestFolder_2");
2690 printf("CreateNewFolder err [%d]\n", iErr
);
2694 HFS_fsOps
.fsops_reclaim( psTestFolder
);
2696 // Read volume header & validate unmount is cleared
2697 if (ReadUnMountBit(psRootNode
, &uUnMountBit
)) {
2702 printf("uUnMountBit is set though it should be cleared\n");
2708 HFS_fsOps
.fsops_sync(psRootNode
);
2710 // Read volume header & validate unmount is set
2711 if (ReadUnMountBit(psRootNode
, &uUnMountBit
)) {
2715 printf("uUnMountBit is cleared though it should be set\n");
2724 static int HFSTest_OneSync( UVFSFileNode RootNode
) {
2726 char pcFolderName
[256];
2728 printf("HFSTest_OneSync\n");
2730 for(unsigned u
=0; u
<5; u
++) {
2731 UVFSFileNode TestFolder
= NULL
;
2732 sprintf(pcFolderName
, "TestFolder_%u", u
);
2734 iErr
= CreateNewFolder( RootNode
, &TestFolder
, pcFolderName
);
2735 printf("CreateNewFolder err [%d]\n", iErr
);
2738 HFS_fsOps
.fsops_reclaim( TestFolder
);
2741 for(unsigned u
=0; u
<5; u
++) {
2742 bool bFound
= false;
2743 sprintf(pcFolderName
, "TestFolder_%u", u
);
2744 read_directory_and_search_for_name( RootNode
, pcFolderName
, &bFound
, NULL
, 0);
2747 printf("Error: %s wasn't found in Root.\n", pcFolderName
);
2752 printf("%s found in Root!\n", pcFolderName
);
2756 printf("Calling Sync\n");
2757 HFS_fsOps
.fsops_sync(RootNode
);
2763 HFSTest_MakeDir( UVFSFileNode RootNode
)
2767 printf("HFSTest_MakeDir\n");
2769 UVFSFileNode TestFolder
= NULL
;
2770 iErr
= CreateNewFolder( RootNode
, &TestFolder
, "TestFolder");
2771 printf("CreateNewFolder err [%d]\n", iErr
);
2775 bool bFound
= false;
2776 read_directory_and_search_for_name( RootNode
, "TestFolder", &bFound
, NULL
, 0);
2779 printf("Error: TestFolder wasn't found in Root.\n");
2784 printf("TestFolder found in Root!\n");
2788 iErr
= RemoveFolder(RootNode
,"TestFolder");
2789 printf("Remove Folder D1 from Root err [%d]\n", iErr
);
2794 read_directory_and_search_for_name( RootNode
, "TestFolder", &bFound
, NULL
, 0 );
2797 printf("Found deleted dir!");
2801 HFS_fsOps
.fsops_reclaim( TestFolder
);
2807 HFSTest_MakeDirAndKeep( UVFSFileNode psRootNode
)
2810 char pcFolderName
[256];
2812 printf("HFSTest_MakeDirAndKeep\n");
2814 for(unsigned u
=0; u
<100; u
++) {
2815 UVFSFileNode TestFolder
= NULL
;
2816 sprintf(pcFolderName
, "TestFolder_%u", u
);
2817 iErr
= CreateNewFolder( psRootNode
, &TestFolder
, pcFolderName
);
2818 printf("CreateNewFolder err [%d]\n", iErr
);
2821 usleep(guSyncerPeriod
* 10); // Allow the syncer to run (at 1/100th rate)
2823 HFS_fsOps
.fsops_reclaim( TestFolder
);
2826 for(unsigned u
=0; u
<100; u
++) {
2827 bool bFound
= false;
2828 sprintf(pcFolderName
, "TestFolder_%u", u
);
2829 read_directory_and_search_for_name( psRootNode
, pcFolderName
, &bFound
, NULL
, 0);
2832 printf("Error: %s wasn't found in Root.\n", pcFolderName
);
2837 printf("%s found in Root!\n", pcFolderName
);
2845 HFSTest_ReadDefragmentFile( UVFSFileNode RootNode
)
2850 printf("HFSTest_ReadDefragmentFile\n");
2853 UVFSFileNode DeFragmentFile
= NULL
;
2854 iErr
= HFS_fsOps
.fsops_lookup( RootNode
, "defragment1.bin", &DeFragmentFile
);
2855 printf("Lookup err [%d]\n", iErr
);
2859 UVFSFileAttributes sOutAttr
;
2860 iErr
= HFS_fsOps
.fsops_getattr( DeFragmentFile
, &sOutAttr
);
2861 printf("GetAttr err [%d]\n", iErr
);
2865 #define FILE_SIZE (1638400)
2866 if ( sOutAttr
.fa_allocsize
!= FILE_SIZE
|| sOutAttr
.fa_size
!= FILE_SIZE
)
2868 printf("Wrong size [%llu\n] [%llu\n]\n", sOutAttr
.fa_size
, sOutAttr
.fa_allocsize
);
2872 void* pvReadBuf
= malloc(FILE_SIZE
);
2873 memset(pvReadBuf
, 0, FILE_SIZE
);
2875 size_t iActuallyRead
;
2876 iErr
= HFS_fsOps
.fsops_read( DeFragmentFile
, 0, FILE_SIZE
, pvReadBuf
, &iActuallyRead
);
2878 HFS_fsOps
.fsops_reclaim( DeFragmentFile
);
2882 printf("HFS_fsOps.fsops_read return status %d\n", iErr
);
2887 if ( iActuallyRead
!= FILE_SIZE
)
2889 printf("iActuallyRead != FILE_SIZE %lu\n", iActuallyRead
);
2894 uint32_t uDetectedNum
= 0;
2895 char pcDetectedNum
[17] = {0};
2896 for ( uint32_t uIdx
=0; uIdx
<FILE_SIZE
/16; uIdx
++ )
2898 memcpy(pcDetectedNum
, pvReadBuf
+ uIdx
*16, 16);
2899 sscanf(pcDetectedNum
, "%u", &uDetectedNum
);
2901 if ( uIdx
+1 != uDetectedNum
)
2903 printf("Read failed. Expected [%u], detected [%u]\n", uIdx
, uDetectedNum
);
2914 HFSTest_RemoveDir( UVFSFileNode RootNode
)
2918 UVFSFileNode MainDir
= NULL
;
2919 iErr
= HFS_fsOps
.fsops_lookup( RootNode
, "MainDir", &MainDir
);
2922 printf("Failed to lookup for main dir\n");
2926 // Try to delete non empty directoy.
2927 iErr
= HFS_fsOps
.fsops_rmdir( RootNode
, "MainDir" );
2928 if ( iErr
!= ENOTEMPTY
)
2930 printf( "Return status is [%d], expected [%d]\n", iErr
, ENOTEMPTY
);
2934 // Delete empty dirs.. Dir[1..10];
2936 for ( int iDirIdx
=1; iDirIdx
<11; iDirIdx
++ )
2938 memset( pcDirName
, 0, sizeof(pcDirName
) );
2939 sprintf( pcDirName
, "Dir%d", iDirIdx
);
2941 // Try to delete empty directoy.
2942 iErr
= HFS_fsOps
.fsops_rmdir( MainDir
, pcDirName
);
2943 printf( "remove dir ended with err [%d]\n", iErr
);
2950 // Reclaim main dir.
2951 HFS_fsOps
.fsops_reclaim( MainDir
);
2953 // Now, try to delete empty main directoy.
2954 iErr
= HFS_fsOps
.fsops_rmdir( RootNode
, "MainDir" );
2957 printf( "Failed to remove main dir [%d]\n", iErr
);
2961 // Make sure main directory deleted.
2962 iErr
= HFS_fsOps
.fsops_lookup( RootNode
, "MainDir", &MainDir
);
2965 printf("Main dir still exist.\n");
2969 // Try to remove unexisting directory
2970 iErr
= HFS_fsOps
.fsops_rmdir( RootNode
, "MainDir" );
2971 if ( iErr
!= ENOENT
)
2973 printf( "Expected [%d], detected [%d]\n", ENOENT
, iErr
);
2981 HFSTest_Remove( UVFSFileNode RootNode
)
2985 #define NUM_OF_FILES (2)
2987 char* ppcFilesNames
[NUM_OF_FILES
] = { "SpecialFileName+-)(*&^%$#@\\!\\}\\{~~<>||??\\.txt", "file1.txt" };
2989 for ( uint8_t uIdx
=0; uIdx
<NUM_OF_FILES
; uIdx
++ )
2991 bool bFound
= false;
2992 read_directory_and_search_for_name( RootNode
, ppcFilesNames
[uIdx
], &bFound
, NULL
, 0);
2995 printf( "Failed to found [%s] status [%d]\n", ppcFilesNames
[uIdx
], iErr
);
2999 iErr
= HFS_fsOps
.fsops_remove( RootNode
, ppcFilesNames
[uIdx
], NULL
);
3002 printf( "Failed to remove [%s] status [%d]\n", ppcFilesNames
[uIdx
], iErr
);
3007 read_directory_and_search_for_name( RootNode
, ppcFilesNames
[uIdx
], &bFound
, NULL
, 0);
3010 printf( "Found [%s] status [%d]\n", ppcFilesNames
[uIdx
], iErr
);
3014 iErr
= HFS_fsOps
.fsops_remove( RootNode
, ppcFilesNames
[uIdx
], NULL
);
3015 if ( iErr
!= ENOENT
)
3017 printf( "Removed deleted file [%s] status [%d]\n", ppcFilesNames
[uIdx
], iErr
);
3025 static void SetExpectedAttr(char* pcName
, uint32_t uType
, UVFSDirEntryAttr
* psAttr
)
3027 psAttr
->dea_nameoff
= UVFS_DIRENTRYATTR_NAMEOFF
;
3028 memcpy (UVFS_DIRENTRYATTR_NAMEPTR(psAttr
),pcName
, strlen(pcName
) + 1);
3029 psAttr
->dea_attrs
.fa_type
= uType
;
3033 HFSTest_ReadDir( UVFSFileNode RootNode
)
3037 uint32_t uEntrySize
= sizeof(UVFSDirEntryAttr
) + MAX_UTF8_NAME_LENGTH
;
3038 UVFSDirEntryAttr
*psReadDirTestsData
= malloc(6*uEntrySize
);
3039 if (psReadDirTestsData
== NULL
)
3042 UVFSDirEntryAttr
*psCurrentReadDirTestsData
= psReadDirTestsData
;
3043 SetExpectedAttr(".", UVFS_FA_TYPE_DIR
, psCurrentReadDirTestsData
);
3044 psCurrentReadDirTestsData
= (UVFSDirEntryAttr
*) ((void*) psCurrentReadDirTestsData
+ uEntrySize
);
3045 SetExpectedAttr("..", UVFS_FA_TYPE_DIR
, psCurrentReadDirTestsData
);
3046 psCurrentReadDirTestsData
= (UVFSDirEntryAttr
*) ((void*) psCurrentReadDirTestsData
+ uEntrySize
);
3047 SetExpectedAttr(".DS_Store", UVFS_FA_TYPE_FILE
, psCurrentReadDirTestsData
);
3048 psCurrentReadDirTestsData
= (UVFSDirEntryAttr
*) ((void*) psCurrentReadDirTestsData
+ uEntrySize
);
3049 SetExpectedAttr("D1", UVFS_FA_TYPE_DIR
, psCurrentReadDirTestsData
);
3050 psCurrentReadDirTestsData
= (UVFSDirEntryAttr
*) ((void*) psCurrentReadDirTestsData
+ uEntrySize
);
3051 SetExpectedAttr("F1", UVFS_FA_TYPE_FILE
, psCurrentReadDirTestsData
);
3052 psCurrentReadDirTestsData
= (UVFSDirEntryAttr
*) ((void*) psCurrentReadDirTestsData
+ uEntrySize
);
3053 SetExpectedAttr("L1", UVFS_FA_TYPE_SYMLINK
, psCurrentReadDirTestsData
);
3056 // {.pcTestName = ".", .uTyppe = UVFS_FA_TYPE_DIR},
3057 // {.pcTestName = "..", .uTyppe = UVFS_FA_TYPE_DIR},
3058 // {.pcTestName = ".DS_Store", .uTyppe = UVFS_FA_TYPE_FILE},
3059 // {.pcTestName = "D1", .uTyppe = UVFS_FA_TYPE_DIR},
3060 // {.pcTestName = "F1", .uTyppe = UVFS_FA_TYPE_FILE},
3061 // {.pcTestName = "L1", .uTyppe = UVFS_FA_TYPE_SYMLINK},
3065 UVFSFileNode MainDir
= NULL
;
3066 iErr
= HFS_fsOps
.fsops_lookup( RootNode
, "D1", &MainDir
);
3067 printf("Lookup err [%d]\n", iErr
);
3071 iErr
= read_directory_and_search_for_name( MainDir
, "D1", &bFound
, psReadDirTestsData
, 6);
3072 free(psReadDirTestsData
);
3073 // Reclaim main dir.
3074 HFS_fsOps
.fsops_reclaim(MainDir
);
3080 HFSTest_ReadDirAttr( UVFSFileNode RootNode
)
3084 // struct ReadDirTestData_s psReadDirTestsData[] = {
3085 // {.pcTestName = ".DS_Store", .uTyppe = UVFS_FA_TYPE_FILE, .uSize = 6148, .uNlink = 1, .uAllocatedSize = 8192},
3086 // {.pcTestName = "D1", .uTyppe = UVFS_FA_TYPE_DIR, .uSize = 0, .uNlink = 2, .uAllocatedSize = 0},
3087 // {.pcTestName = "F1", .uTyppe = UVFS_FA_TYPE_FILE, .uSize = 4, .uNlink = 1, .uAllocatedSize = 4096},
3088 // {.pcTestName = "L1", .uTyppe = UVFS_FA_TYPE_SYMLINK, .uSize = 23, .uNlink = 1, .uAllocatedSize = 4096},
3091 UVFSFileNode MainDir
= NULL
;
3092 iErr
= HFS_fsOps
.fsops_lookup( RootNode
, "D1", &MainDir
);
3093 printf("Lookup err [%d]\n", iErr
);
3097 uint32_t uEntrySize
= sizeof(UVFSDirEntryAttr
) + MAX_UTF8_NAME_LENGTH
;
3098 UVFSDirEntryAttr
*psReadDirTestsData
= malloc(4*uEntrySize
);
3099 if (psReadDirTestsData
== NULL
)
3102 UVFSFileNode psVnode
= NULL
;
3103 UVFSFileNode psVnode1
= NULL
;
3104 UVFSFileNode psVnode2
= NULL
;
3105 UVFSFileNode psVnode3
= NULL
;
3106 UVFSDirEntryAttr
*psCurrentReadDirTestsData
= psReadDirTestsData
;
3107 SetExpectedAttr(".DS_Store", UVFS_FA_TYPE_FILE
, psCurrentReadDirTestsData
);
3108 iErr
= HFS_fsOps
.fsops_lookup( MainDir
, ".DS_Store", &psVnode
);
3109 iErr
= HFS_fsOps
.fsops_getattr( psVnode
, &psCurrentReadDirTestsData
->dea_attrs
);
3110 psCurrentReadDirTestsData
= (UVFSDirEntryAttr
*) ((void*) psCurrentReadDirTestsData
+ uEntrySize
);
3111 SetExpectedAttr("D1", UVFS_FA_TYPE_DIR
, psCurrentReadDirTestsData
);
3112 iErr
= HFS_fsOps
.fsops_lookup( MainDir
, "D1", &psVnode1
);
3113 iErr
= HFS_fsOps
.fsops_getattr( psVnode1
, &psCurrentReadDirTestsData
->dea_attrs
);
3114 psCurrentReadDirTestsData
= (UVFSDirEntryAttr
*) ((void*) psCurrentReadDirTestsData
+ uEntrySize
);
3115 SetExpectedAttr("F1", UVFS_FA_TYPE_FILE
, psCurrentReadDirTestsData
);
3116 iErr
= HFS_fsOps
.fsops_lookup( MainDir
, "F1", &psVnode2
);
3117 iErr
= HFS_fsOps
.fsops_getattr( psVnode2
, &psCurrentReadDirTestsData
->dea_attrs
);
3118 psCurrentReadDirTestsData
= (UVFSDirEntryAttr
*) ((void*) psCurrentReadDirTestsData
+ uEntrySize
);
3119 SetExpectedAttr("L1", UVFS_FA_TYPE_SYMLINK
, psCurrentReadDirTestsData
);
3120 iErr
= HFS_fsOps
.fsops_lookup( MainDir
, "L1", &psVnode3
);
3121 iErr
= HFS_fsOps
.fsops_getattr( psVnode3
, &psCurrentReadDirTestsData
->dea_attrs
);
3123 iErr
= ReadDirAttr(MainDir
, psReadDirTestsData
, 4);
3124 free(psReadDirTestsData
);
3125 // Reclaim main dir.
3126 HFS_fsOps
.fsops_reclaim(MainDir
);
3127 HFS_fsOps
.fsops_reclaim(psVnode
);
3128 HFS_fsOps
.fsops_reclaim(psVnode1
);
3129 HFS_fsOps
.fsops_reclaim(psVnode2
);
3130 HFS_fsOps
.fsops_reclaim(psVnode3
);
3136 HFSTest_ReadSymlink( UVFSFileNode RootNode
)
3138 void* pvBuf
= malloc(200);
3139 assert( pvBuf
!= NULL
);
3140 memset( pvBuf
, 0, 200 );
3141 char* pcSymLinkContent
= "/just/for/check/that/symlink/work/properly";
3142 char* pcSymlinkFileName
= "symlinkfile";
3143 UVFSFileNode outNode
= NULL
;
3145 int iErr
= HFS_fsOps
.fsops_lookup(RootNode
, pcSymlinkFileName
, &outNode
);
3147 printf("Dir read failed, D2 wasn't found in Root");
3149 // Verify Symlink content
3150 size_t iActuallyRead
;
3151 UVFSFileAttributes sOutAttr
= {0};
3152 iErr
= HFS_fsOps
.fsops_readlink( outNode
, pvBuf
, 200, &iActuallyRead
, &sOutAttr
);
3155 printf( "fsops_readlink failed with eror code : %d\n", iErr
);
3159 if ( strcmp( pvBuf
, pcSymLinkContent
) != 0 )
3161 printf( "Read bad symlink content\n" );
3166 HFS_fsOps
.fsops_reclaim( outNode
);
3176 HFSTest_Symlink( UVFSFileNode RootNode
)
3179 #define SYMLINK_MODE \
3180 ( UVFS_FA_MODE_USR(UVFS_FA_MODE_RWX) | \
3181 UVFS_FA_MODE_GRP(UVFS_FA_MODE_R) | \
3182 UVFS_FA_MODE_OTH(UVFS_FA_MODE_R | UVFS_FA_MODE_X) )
3184 void* pvBuf
= malloc(200);
3185 assert( pvBuf
!= NULL
);
3186 memset( pvBuf
, 0xff, 200 );
3187 char* pcSymLinkContent
= "/just/for/check/that/symlink/work/properly";
3188 char* pcSymlinkFileName
= "symlinkfile";
3189 UVFSFileAttributes sAttr
= {0};
3190 sAttr
.fa_validmask
= UVFS_FA_VALID_MODE
;
3191 sAttr
.fa_type
= UVFS_FA_TYPE_SYMLINK
;
3192 sAttr
.fa_mode
= SYMLINK_MODE
;
3193 UVFSFileNode outNode
= NULL
;
3196 int iErr
= HFS_fsOps
.fsops_symlink( RootNode
, pcSymlinkFileName
, pcSymLinkContent
, &sAttr
, &outNode
);
3199 printf( "fsops_symlink failed with eror code : %d\n", iErr
);
3203 // Enable once vnode functionality will be merged.
3205 // Verify Symlink content
3206 size_t iActuallyRead
;
3207 UVFSFileAttributes sOutAttr
= {0};
3208 iErr
= HFS_fsOps
.fsops_readlink( outNode
, pvBuf
, 200, &iActuallyRead
, &sOutAttr
);
3211 printf( "fsops_readlink failed with eror code : %d\n", iErr
);
3215 if ( strcmp( pvBuf
, pcSymLinkContent
) != 0 )
3217 printf( "Read bad symlink content\n" );
3222 if ( sOutAttr
.fa_mode
!= SYMLINK_MODE
)
3224 printf( "Mode mismatch [%d != %d]\n", sOutAttr
.fa_mode
, SYMLINK_MODE
);
3229 if ( sOutAttr
.fa_type
!= UVFS_FA_TYPE_SYMLINK
)
3231 printf( "Type mismatch\n" );
3237 HFS_fsOps
.fsops_reclaim( outNode
);
3240 iErr
= HFS_fsOps
.fsops_remove( RootNode
, pcSymlinkFileName
, NULL
);
3243 printf( "Failed to remove symlink %d\n", iErr
);
3247 bool bFound
= false;
3248 read_directory_and_search_for_name( RootNode
, pcSymlinkFileName
, &bFound
, NULL
, 0 );
3251 printf( "Failed to remove symlink\n");
3263 static int HFSTest_SymlinkOnFile( UVFSFileNode pRootNode
) {
3264 // This test creates a file and a folder on root.
3265 // It then tries to create a SymLink inside the folder and expects pass,
3266 // and creates a SymLink inside a file and expects a failure.
3267 printf("HFSTest_SymlinkOnFile\n");
3269 char *pcFolderName
= "NewFolder";
3270 char *pcFileName
= "NewFile.txt";
3271 uint32_t uFileLen
= 985;
3272 char *pcSymlinkFilename
= "SymLinkFile";
3273 char *pcSymLinkContent
= "/SymlinkContent";
3275 UVFSFileNode pFolderNode
= NULL
;
3276 UVFSFileNode pFileNode
= NULL
;
3277 UVFSFileNode pSymLinkOnRootNode
= NULL
;
3278 UVFSFileNode pSymLinkOnFolderNode
= NULL
;
3279 UVFSFileNode pSymLinkOnFileNode
= NULL
;
3281 iErr
= CreateNewFolder( pRootNode
, &pFolderNode
, pcFolderName
);
3282 printf("CreateNewFolder err [%d]\n", iErr
);
3284 printf("Error: CreateNewFolder failed.\n");
3288 //Create new file with size 512
3289 CreateNewFile(pRootNode
, &pFileNode
, pcFileName
, uFileLen
);
3290 printf("Create %s Len %u err [%d]\n", pcFileName
, uFileLen
, iErr
);
3292 printf("Error: CreateNewFile failed.\n");
3296 bool bFound
= false;
3297 read_directory_and_search_for_name( pRootNode
, pcFolderName
, &bFound
, NULL
, 0);
3299 printf("Error: %s wasn't found in Root.\n", pcFolderName
);
3302 printf("%s found in Root!\n", pcFolderName
);
3305 read_directory_and_search_for_name( pRootNode
, pcFileName
, &bFound
, NULL
, 0);
3307 printf("Error: %s wasn't found in Root.\n", pcFileName
);
3310 printf("%s found in Root!\n", pcFileName
);
3313 UVFSFileAttributes sAttr
= {0};
3314 sAttr
.fa_validmask
= UVFS_FA_VALID_MODE
;
3315 sAttr
.fa_type
= UVFS_FA_TYPE_SYMLINK
;
3316 sAttr
.fa_mode
= SYMLINK_MODE
;
3318 // Create Symlink on root
3319 iErr
= HFS_fsOps
.fsops_symlink( pRootNode
, pcSymlinkFilename
, pcSymLinkContent
, &sAttr
, &pSymLinkOnRootNode
);
3321 printf( "fsops_symlink failed to create %s with eror code : %d\n", pcSymlinkFilename
, iErr
);
3325 // Create Symlink on folder
3326 iErr
= HFS_fsOps
.fsops_symlink( pFolderNode
, pcSymlinkFilename
, pcSymLinkContent
, &sAttr
, &pSymLinkOnFolderNode
);
3328 printf( "fsops_symlink failed to create %s inside %s with eror code : %d\n", pcSymlinkFilename
, pcFolderName
, iErr
);
3332 // Create Symlink on file
3333 iErr
= HFS_fsOps
.fsops_symlink( pFileNode
, pcSymlinkFilename
, pcSymLinkContent
, &sAttr
, &pSymLinkOnFileNode
);
3335 printf( "fsops_symlink error: did not fail to create %s inside %s with eror code : %d\n", pcSymlinkFilename
, pcFileName
, iErr
);
3340 assert(pSymLinkOnFileNode
== NULL
);
3341 HFS_fsOps
.fsops_reclaim( pFileNode
);
3342 HFS_fsOps
.fsops_reclaim( pFolderNode
);
3343 HFS_fsOps
.fsops_reclaim( pSymLinkOnFolderNode
);
3344 HFS_fsOps
.fsops_reclaim( pSymLinkOnRootNode
);
3350 HFSTest_SetAttr( UVFSFileNode RootNode
)
3354 UVFSFileNode Dir1
= NULL
;
3355 iErr
= HFS_fsOps
.fsops_lookup(RootNode
, "D2", &Dir1
);
3357 printf("Dir read failed, D2 wasn't found in Root");
3358 UVFSFileNode File1
= NULL
;
3359 iErr
= HFS_fsOps
.fsops_lookup(Dir1
, "a.txt", &File1
);
3363 printf("File not found!\n");
3368 // Set Attr, make F1 larger
3369 iErr
= SetAttrChangeSize(File1
,12*1024);
3370 printf("SetAttrChangeSize to 12K err [%d]\n",iErr
);
3376 iErr
= SetAttrChangeSize(File1
,4*1024);
3377 printf("SetAttrChangeSize to 4 err [%d]\n",iErr
);
3383 iErr
= SetAttrChangeSize(File1
,0*1024);
3384 printf("SetAttrChangeSize to 0 err [%d]\n",iErr
);
3390 iErr
= SetAttrChangeSize(File1
,8*1024*1024);
3391 printf("SetAttrChangeSize to 120MB err [%d]\n",iErr
);
3397 iErr
= SetAttrChangeMode(File1
, UVFS_FA_MODE_GRP(UVFS_FA_MODE_RWX
) | UVFS_FA_MODE_USR(UVFS_FA_MODE_RWX
));
3398 printf("Changed file mode to RO err[ %d]\n",iErr
);
3404 iErr
= SetAttrChangeUidGid(File1
, 222, 555);
3406 printf("Changed Uid and Gid err [%d]\n", iErr
);
3412 iErr
= SetAttrChangeAtimeMtime(File1
);
3414 printf("Changed Atime and Mtime err [%d]\n", iErr
);
3420 HFS_fsOps
.fsops_reclaim(File1
);
3422 HFS_fsOps
.fsops_reclaim(Dir1
);
3424 iErr
= HFS_fsOps
.fsops_lookup(RootNode
, "D2", &Dir1
);
3426 printf("Dir read failed, D2 wasn't found in Root");
3427 iErr
= HFS_fsOps
.fsops_lookup(Dir1
, "a.txt", &File1
);
3430 printf("File not found! (2)\n");
3434 iErr
= SetAttrChangeAtimeMtime(File1
);
3436 printf("Changed Atime and Mtime (2) err [%d]\n", iErr
);
3442 HFS_fsOps
.fsops_reclaim(File1
);
3444 HFS_fsOps
.fsops_reclaim(Dir1
);
3449 static char* gpcFSAttrs
[] = {
3450 UVFS_FSATTR_PC_LINK_MAX
,
3451 UVFS_FSATTR_PC_NAME_MAX
,
3452 UVFS_FSATTR_PC_NO_TRUNC
,
3453 UVFS_FSATTR_PC_FILESIZEBITS
,
3454 UVFS_FSATTR_PC_XATTR_SIZE_BITS
,
3455 UVFS_FSATTR_BLOCKSIZE
,
3457 UVFS_FSATTR_TOTALBLOCKS
,
3458 UVFS_FSATTR_BLOCKSFREE
,
3459 UVFS_FSATTR_BLOCKSAVAIL
,
3460 UVFS_FSATTR_BLOCKSUSED
,
3462 UVFS_FSATTR_FSTYPENAME
,
3463 UVFS_FSATTR_FSSUBTYPE
,
3464 UVFS_FSATTR_VOLNAME
,
3465 UVFS_FSATTR_VOLUUID
,
3466 UVFS_FSATTR_CAPS_FORMAT
,
3467 UVFS_FSATTR_CAPS_INTERFACES
,
3468 UVFS_FSATTR_LAST_MTIME
,
3469 UVFS_FSATTR_MOUNT_TIME
3473 HFSTest_GetFSAttr( UVFSFileNode RootNode
)
3478 UVFSFSAttributeValue
* psAttrVal
= (UVFSFSAttributeValue
*)malloc(uLen
);
3479 assert( psAttrVal
);
3481 for ( uint32_t uIdx
=0; uIdx
<ARR_LEN(gpcFSAttrs
); uIdx
++ )
3483 memset( psAttrVal
, 0, uLen
);
3485 iErr
= HFS_fsOps
.fsops_getfsattr( RootNode
, gpcFSAttrs
[uIdx
], psAttrVal
, uLen
, &uRetLen
);
3488 printf( "fsops_getfsattr attr = %s return with error code [%d]\n", gpcFSAttrs
[uIdx
], iErr
);
3492 printf( "FSAttr = [%s] Value = [", gpcFSAttrs
[uIdx
]);
3493 if ( UVFS_FSATTR_IS_BOOL( gpcFSAttrs
[uIdx
] ) )
3495 printf( psAttrVal
->fsa_bool
? "true" : "false" );
3497 else if ( UVFS_FSATTR_IS_NUMBER( gpcFSAttrs
[uIdx
] ) )
3499 printf( "%llu", psAttrVal
->fsa_number
);
3501 else if ( UVFS_FSATTR_IS_OPAQUE( gpcFSAttrs
[uIdx
] ) )
3504 for ( uint32_t uOp
=0; uOp
<uRetLen
; uOp
++ )
3506 printf( "%x", psAttrVal
->fsa_opaque
[uOp
] );
3509 else if ( UVFS_FSATTR_IS_STRING( gpcFSAttrs
[uIdx
] ) )
3511 printf( "%s", psAttrVal
->fsa_string
);
3526 HFSTest_WriteRead( UVFSFileNode RootNode
)
3528 #define FILENAME "NewFileForTest"
3529 #define MAXFILESIZE (1024*1024*1024)
3532 UVFSFileNode psFile
= NULL
;
3533 size_t iActuallyWrite
= 0;
3534 size_t iActuallyRead
= 0;
3535 void* pvOutBuf
= malloc(MAXFILESIZE
);
3536 void* pvInBuf
= malloc(MAXFILESIZE
);
3537 assert( pvOutBuf
!= NULL
&& pvInBuf
!= NULL
);
3538 uint64_t* puOutBuf
= pvOutBuf
;
3539 uint64_t* puInBuf
= pvInBuf
;
3541 // Create new file with size 50,000 Bytes
3542 assert( CreateNewFile( RootNode
, &psFile
, FILENAME
, 50000 ) == 0 );
3544 // lets write 10,000 Bytes with 0xCD
3545 memset(pvOutBuf
, 0, MAXFILESIZE
);
3546 memset(pvInBuf
, 0, MAXFILESIZE
);
3548 memset(pvOutBuf
, 0xCD, 10000);
3550 assert( HFS_fsOps
.fsops_write( psFile
, 0, 10000, pvOutBuf
, &iActuallyWrite
) == 0 );
3551 assert( HFS_fsOps
.fsops_read( psFile
, 0, 10000, pvInBuf
, &iActuallyRead
) == 0 );
3554 for ( uint64_t uIdx
=0; uIdx
<(MAXFILESIZE
/sizeof(uint64_t)); uIdx
++ )
3556 assert( puInBuf
[uIdx
] == puOutBuf
[uIdx
] );
3559 // Lets extend the file to 100,000 Bytes...
3560 memset(pvOutBuf
+10000, 0xED, 90000);
3561 assert( HFS_fsOps
.fsops_write( psFile
, 10000, 90000, pvOutBuf
+10000, &iActuallyWrite
) == 0 );
3562 assert( HFS_fsOps
.fsops_read( psFile
, 0, 100000, pvInBuf
, &iActuallyRead
) == 0 );
3565 for ( uint64_t uIdx
=0; uIdx
<(MAXFILESIZE
/sizeof(uint64_t)); uIdx
++ )
3567 assert( puInBuf
[uIdx
] == puOutBuf
[uIdx
] );
3570 memset(pvOutBuf
, 0, MAXFILESIZE
);
3571 memset(pvInBuf
, 0, MAXFILESIZE
);
3572 assert( SetAttrChangeSize(psFile
, 10000) == 0 );
3573 memset(pvOutBuf
, 0xCD, 10000);
3574 memset(pvOutBuf
+20000, 0xBB, 10000);
3576 assert( HFS_fsOps
.fsops_write( psFile
, 20000, 10000, pvOutBuf
+20000, &iActuallyWrite
) == 0 );
3577 assert( HFS_fsOps
.fsops_read( psFile
, 0, 30000, pvInBuf
, &iActuallyRead
) == 0 );
3580 for ( uint64_t uIdx
=0; uIdx
<(MAXFILESIZE
/sizeof(uint64_t)); uIdx
++ )
3582 assert( puInBuf
[uIdx
] == puOutBuf
[uIdx
] );
3585 HFS_fsOps
.fsops_reclaim( psFile
);
3594 HFSTest_RandomIO( UVFSFileNode RootNode
)
3596 #define MAX_IO_SIZE (1024*1024)
3597 #define MAX_IO_OFFSET (80*MAX_IO_SIZE)
3598 #define TEST_RUN_TIME_SEC (30)
3601 UVFSFileNode psFile
;
3602 static mach_timebase_info_data_t sTimebaseInfo
;
3603 mach_timebase_info(&sTimebaseInfo
);
3605 void* pvWriteBuf
= malloc(MAX_IO_SIZE
);
3606 void* pvReadBuf
= malloc(MAX_IO_SIZE
);
3608 int* puBuf
= pvWriteBuf
;
3609 for ( uint64_t uIdx
=0; uIdx
<(MAX_IO_SIZE
/sizeof(int)); uIdx
++ )
3611 puBuf
[uIdx
] = rand();
3614 iErr
= CreateNewFile( RootNode
, &psFile
, "SimpleFile", 0 );
3617 uint64_t start
= mach_absolute_time();
3618 uint64_t elapsedSec
= 0;
3619 // while( elapsedSec < TEST_RUN_TIME_SEC )
3620 for(uint32_t uWriteReadCnt
=1000; uWriteReadCnt
; uWriteReadCnt
--)
3622 uint64_t uNextIOSize
= rand() % MAX_IO_SIZE
;
3623 uint64_t uNextIOOffset
= rand() % MAX_IO_OFFSET
;
3625 printf("uNextIOSize = %llu, uNextIOOffset = %llu\n", uNextIOSize
, uNextIOOffset
);
3627 size_t iActuallyWrite
;
3628 size_t iActuallyRead
;
3630 iErr
= HFS_fsOps
.fsops_write( psFile
, uNextIOOffset
, uNextIOSize
, pvWriteBuf
, &iActuallyWrite
);
3632 iErr
= HFS_fsOps
.fsops_read( psFile
, uNextIOOffset
, uNextIOSize
, pvReadBuf
, &iActuallyRead
);
3635 uint8_t* puRead
= pvReadBuf
;
3636 uint8_t* puWrite
= pvWriteBuf
;
3637 for ( uint64_t uIdx
=0; uIdx
<uNextIOSize
; uIdx
++ )
3639 assert( puRead
[uIdx
] == puWrite
[uIdx
] );
3642 uint64_t end
= mach_absolute_time();
3643 uint64_t elapsed
= end
- start
;
3644 uint64_t elapsedNano
= elapsed
* sTimebaseInfo
.numer
/ sTimebaseInfo
.denom
;
3645 elapsedSec
= elapsedNano
/ 1000 / 1000 / 1000;
3651 HFS_fsOps
.fsops_reclaim(psFile
);
3657 HFSTest_HardLink( UVFSFileNode RootNode
)
3661 // Validate files exist on media
3662 UVFSFileNode psOriginalFile
= NULL
;
3663 iErr
= HFS_fsOps
.fsops_lookup( RootNode
, "original_file.txt", &psOriginalFile
);
3664 printf("Lookup for original file err [%d]\n", iErr
);
3668 UVFSFileNode psFirstLink
= NULL
;
3669 iErr
= HFS_fsOps
.fsops_lookup( RootNode
, "first_link.txt", &psFirstLink
);
3670 printf("Lookup for original file err [%d]\n", iErr
);
3674 UVFSFileNode psDirectory
= NULL
;
3675 iErr
= HFS_fsOps
.fsops_lookup( RootNode
, "dir", &psDirectory
);
3676 printf("Lookup for original file err [%d]\n", iErr
);
3680 UVFSFileNode psSecondLink
= NULL
;
3681 iErr
= HFS_fsOps
.fsops_lookup( psDirectory
, "second_link.txt", &psSecondLink
);
3682 printf("Lookup for original file err [%d]\n", iErr
);
3687 UVFSFileAttributes sOutAttrs
;
3688 iErr
= HFS_fsOps
.fsops_getattr(psOriginalFile
, &sOutAttrs
);
3689 printf("GetAttr for original file err [%d]\n", iErr
);
3693 if (sOutAttrs
.fa_nlink
!= 3)
3695 printf("nlink of original file should be 3, got [%d]\n", sOutAttrs
.fa_nlink
);
3699 void* pvOriginalFileBuf
= malloc(sOutAttrs
.fa_size
);
3700 void* pvFirstLinkeBuf
= malloc(sOutAttrs
.fa_size
);
3701 void* pvSecondLinkeBuf
= malloc(sOutAttrs
.fa_size
);
3702 uint64_t* puOriginalFileBuf
= pvOriginalFileBuf
;
3703 uint64_t* puFirstLinkeBuf
= pvFirstLinkeBuf
;
3704 uint64_t* puSecondLinkeBuf
= pvSecondLinkeBuf
;
3706 size_t iActuallyRead
= 0;
3707 assert( HFS_fsOps
.fsops_read( psOriginalFile
, 0, sOutAttrs
.fa_size
, pvOriginalFileBuf
, &iActuallyRead
) == 0 );
3708 assert( HFS_fsOps
.fsops_read( psFirstLink
, 0, sOutAttrs
.fa_size
, pvFirstLinkeBuf
, &iActuallyRead
) == 0 );
3709 assert( HFS_fsOps
.fsops_read( psSecondLink
, 0, sOutAttrs
.fa_size
, pvSecondLinkeBuf
, &iActuallyRead
) == 0 );
3711 // Lets test if all links has the same content it...
3712 for ( uint64_t uIdx
=0; uIdx
<(sOutAttrs
.fa_size
/sizeof(uint64_t)); uIdx
++ )
3714 assert( puOriginalFileBuf
[uIdx
] == puFirstLinkeBuf
[uIdx
] );
3715 assert( puOriginalFileBuf
[uIdx
] == puSecondLinkeBuf
[uIdx
] );
3718 // Save content of the original file and fill up 0x1000 0xAAs
3719 void* pvNewContentBuf
= malloc(sOutAttrs
.fa_size
+ 1000);
3720 uint64_t* puNewContentBuf
= pvNewContentBuf
;
3722 memcpy(pvNewContentBuf
, pvOriginalFileBuf
,sOutAttrs
.fa_size
);
3723 memset(pvNewContentBuf
+ sOutAttrs
.fa_size
, 0xAA,1000);
3725 assert( HFS_fsOps
.fsops_write( psOriginalFile
, 0, sOutAttrs
.fa_size
+ 1000, pvNewContentBuf
, &iActuallyRead
) == 0 );
3726 free(pvOriginalFileBuf
);
3727 free(pvFirstLinkeBuf
);
3728 free(pvSecondLinkeBuf
);
3730 pvOriginalFileBuf
= malloc(sOutAttrs
.fa_size
+ 1000);
3731 pvFirstLinkeBuf
= malloc(sOutAttrs
.fa_size
+ 1000);
3732 pvSecondLinkeBuf
= malloc(sOutAttrs
.fa_size
+ 1000);
3733 puOriginalFileBuf
= pvOriginalFileBuf
;
3734 puFirstLinkeBuf
= pvFirstLinkeBuf
;
3735 puSecondLinkeBuf
= pvSecondLinkeBuf
;
3737 // Make sure the file and its hardlinks have the new content
3738 assert( HFS_fsOps
.fsops_read( psOriginalFile
, 0, sOutAttrs
.fa_size
+ 1000, pvOriginalFileBuf
, &iActuallyRead
) == 0 );
3739 assert( HFS_fsOps
.fsops_read( psFirstLink
, 0, sOutAttrs
.fa_size
+ 1000, pvFirstLinkeBuf
, &iActuallyRead
) == 0 );
3740 assert( HFS_fsOps
.fsops_read( psSecondLink
, 0, sOutAttrs
.fa_size
+ 1000, pvSecondLinkeBuf
, &iActuallyRead
) == 0 );
3741 for ( uint64_t uIdx
=0; uIdx
<((sOutAttrs
.fa_size
+ 1000)/sizeof(uint64_t)); uIdx
++ )
3743 assert( puOriginalFileBuf
[uIdx
] == puNewContentBuf
[uIdx
] );
3744 assert( puOriginalFileBuf
[uIdx
] == puFirstLinkeBuf
[uIdx
] );
3745 assert( puOriginalFileBuf
[uIdx
] == puSecondLinkeBuf
[uIdx
] );
3748 iErr
= HFS_fsOps
.fsops_remove( RootNode
, "original_file.txt", NULL
);
3749 printf( "Remove original file err [%d]\n", iErr
);
3753 iErr
= HFS_fsOps
.fsops_getattr(psFirstLink
, &sOutAttrs
);
3754 printf("GetAttr for first link err [%d]\n", iErr
);
3758 if (sOutAttrs
.fa_nlink
!= 2)
3760 printf("nlink of first link should be 2, got [%d]\n", sOutAttrs
.fa_nlink
);
3764 RenameFile(psDirectory
, psSecondLink
,"second_link.txt", RootNode
, psFirstLink
,"first_link.txt" );
3766 iErr
= HFS_fsOps
.fsops_getattr(psSecondLink
, &sOutAttrs
);
3767 printf("GetAttr for second link err [%d]\n", iErr
);
3772 if (sOutAttrs
.fa_nlink
!= 2)
3774 printf("nlink of first link should be 2, got [%d]\n", sOutAttrs
.fa_nlink
);
3778 iErr
= HFS_fsOps
.fsops_remove( RootNode
, "first_link.txt", NULL
);
3779 printf( "Remove first link err [%d]\n", iErr
);
3783 free(pvOriginalFileBuf
);
3784 free(pvFirstLinkeBuf
);
3785 free(pvSecondLinkeBuf
);
3786 free(pvNewContentBuf
);
3787 HFS_fsOps
.fsops_reclaim(psOriginalFile
);
3788 HFS_fsOps
.fsops_reclaim(psFirstLink
);
3789 HFS_fsOps
.fsops_reclaim(psSecondLink
);
3790 HFS_fsOps
.fsops_reclaim(psDirectory
);
3796 HFSTest_CreateHardLink( UVFSFileNode RootNode
)
3798 uint32_t uOriginalFileSize
= 500000;
3801 UVFSFileNode psFile
= NULL
;
3802 size_t iActuallyWrite
= 0;
3803 size_t iActuallyRead
= 0;
3804 void* pvOutBuf
= malloc(uOriginalFileSize
);
3805 void* pvInBuf
= malloc(uOriginalFileSize
);
3806 assert( pvOutBuf
!= NULL
&& pvInBuf
!= NULL
);
3807 uint64_t* puOutBuf
= pvOutBuf
;
3808 uint64_t* puInBuf
= pvInBuf
;
3810 // Create the original file with size 500,000 Bytes
3811 iErr
= CreateNewFile( RootNode
, &psFile
, "original_file.txt", uOriginalFileSize
);
3812 assert( iErr
== 0 );
3814 // lets write 10,000 Bytes with 0xCD
3815 memset(pvOutBuf
, 0, uOriginalFileSize
);
3816 memset(pvInBuf
, 0, uOriginalFileSize
);
3818 memset(pvOutBuf
, 0xCD, uOriginalFileSize
);
3820 assert( HFS_fsOps
.fsops_write( psFile
, 0, uOriginalFileSize
, pvOutBuf
, &iActuallyWrite
) == 0 );
3821 assert( HFS_fsOps
.fsops_read( psFile
, 0, uOriginalFileSize
, pvInBuf
, &iActuallyRead
) == 0 );
3824 for ( uint64_t uIdx
=0; uIdx
<(uOriginalFileSize
/sizeof(uint64_t)); uIdx
++ )
3826 assert( puInBuf
[uIdx
] == puOutBuf
[uIdx
] );
3829 UVFSFileNode psDirectory
= NULL
;
3830 assert (CreateNewFolder(RootNode
,&psDirectory
,"dir") == 0);
3831 assert (CreateHardLink(psFile
,RootNode
,"first_link.txt") == 0);
3832 assert (CreateHardLink(psFile
,psDirectory
,"second_link.txt") == 0);
3834 HFS_fsOps
.fsops_reclaim( psFile
);
3835 HFS_fsOps
.fsops_reclaim( psDirectory
);
3837 assert (HFSTest_HardLink( RootNode
) == 0);
3846 HFSTest_RenameToHardlink( UVFSFileNode RootNode
)
3848 UVFSFileNode psFile0
= NULL
;
3849 UVFSFileNode psFile1
= NULL
;
3850 UVFSFileNode psLink
= NULL
;
3851 UVFSFileAttributes sOutAttrs
= {0};
3853 assert ( CreateNewFile( RootNode
, &psFile0
, "simple_file.txt", 0 ) == 0 );
3854 assert ( CreateNewFile( RootNode
, &psFile1
, "original_file.txt", 0 ) == 0 );
3855 assert ( CreateHardLink( psFile1
, RootNode
, "first_link.txt" ) == 0 );
3856 assert ( CreateHardLink( psFile1
, RootNode
, "second_link.txt" ) == 0 );
3857 assert ( HFS_fsOps
.fsops_lookup( RootNode
, "first_link.txt", &psLink
) == 0 );
3858 assert( RenameFile(RootNode
, psFile0
, "simple_file.txt", RootNode
, psLink
, "first_link.txt") == 0 );
3860 assert( HFS_fsOps
.fsops_getattr(psFile1
, &sOutAttrs
) == 0 );
3862 assert( HFS_fsOps
.fsops_reclaim(psFile0
) == 0 );
3863 for ( uint32_t uIdx
=0; uIdx
<sOutAttrs
.fa_nlink
; uIdx
++ )
3864 assert( HFS_fsOps
.fsops_reclaim(psFile1
) == 0 );
3870 HFSTest_JustMount( __unused UVFSFileNode RootNode
)
3875 static int HFSTest_OpenJournal( __unused UVFSFileNode RootNode
) {
3877 printf("HFSTest_OpenJournal:\n");
3882 static int HFSTest_WriteToJournal(UVFSFileNode RootNode
) {
3885 printf("HFSTest_WriteToJournal:\n");
3887 printf("Create a new folder:\n");
3888 UVFSFileNode TestFolder
= NULL
;
3889 iErr
= CreateNewFolder( RootNode
, &TestFolder
, "TestFolder");
3890 printf("CreateNewFolder err [%d]\n", iErr
);
3895 printf("Create new file with size 0:\n");
3896 UVFSFileNode TestFile1
= NULL
;
3897 CreateNewFile(TestFolder
, &TestFile1
, "TestFile.txt",0);
3898 printf("Create TestFile in TestFolder err [%d]\n", iErr
);
3903 printf("Create new file with size 512:\n");
3904 UVFSFileNode TestFile2
= NULL
;
3905 CreateNewFile(TestFolder
, &TestFile2
, "TestFile2.txt",512);
3906 printf("Create TestFile2 in TestFolder err [%d]\n", iErr
);
3911 uint32_t uEntrySize
= sizeof(UVFSDirEntryAttr
) + MAX_UTF8_NAME_LENGTH
;
3912 UVFSDirEntryAttr
*psReadDirTestsData
= malloc(2*uEntrySize
);
3913 if (psReadDirTestsData
== NULL
)
3916 UVFSDirEntryAttr
*psCurrentReadDirTestsData
= psReadDirTestsData
;
3917 SetExpectedAttr("TestFile.txt", UVFS_FA_TYPE_FILE
, psCurrentReadDirTestsData
);
3918 iErr
= HFS_fsOps
.fsops_getattr( TestFile1
, &psCurrentReadDirTestsData
->dea_attrs
);
3919 psCurrentReadDirTestsData
= (UVFSDirEntryAttr
*) ((void*) psCurrentReadDirTestsData
+ uEntrySize
);
3920 SetExpectedAttr("TestFile2.txt", UVFS_FA_TYPE_FILE
, psCurrentReadDirTestsData
);
3921 iErr
= HFS_fsOps
.fsops_getattr( TestFile2
, &psCurrentReadDirTestsData
->dea_attrs
);
3923 printf("Read DIR attr:\n");
3924 iErr
= ReadDirAttr(TestFolder
, psReadDirTestsData
, 2);
3925 free(psReadDirTestsData
);
3926 printf("ReadDirAttr err [%d]\n", iErr
);
3931 printf("Remove File1:\n");
3932 iErr
= RemoveFile(TestFolder
,"TestFile.txt");
3933 printf("Remove File TestFile from TestFolder err [%d]\n", iErr
);
3938 printf("Remove File2:\n");
3939 iErr
= RemoveFile(TestFolder
,"TestFile2.txt");
3940 printf("Remove File TestFile2 from TestFolder err [%d]\n", iErr
);
3945 printf("Remove TestFolder:\n");
3946 iErr
= RemoveFolder(RootNode
,"TestFolder");
3947 printf("Remove Folder TestFolder from Root err [%d]\n", iErr
);
3953 HFS_fsOps
.fsops_reclaim(TestFolder
);
3954 HFS_fsOps
.fsops_reclaim(TestFile1
);
3955 HFS_fsOps
.fsops_reclaim(TestFile2
);
3960 HFSTest_SetXattr( UVFSFileNode RootNode
)
3962 const char * pcAttr
= "com.apple.test.set";
3963 const char * pcAttr2
= "com.apple.test.set2";
3964 char pcData
[] = "This is attribute data";
3965 char pcData2
[] = "This is attribute data 2";
3968 UVFSFileNode TestFile
= NULL
;
3969 iErr
= HFS_fsOps
.fsops_lookup( RootNode
, "kl_set.test", &TestFile
);
3972 printf("Lookup err [%d]\n", iErr
);
3976 // Add Attribute - create
3977 iErr
= HFS_fsOps
.fsops_setxattr(TestFile
, pcAttr
, pcData
, strlen(pcData
)+1, UVFSXattrHowCreate
);
3980 printf("SetAttr err [%d]\n", iErr
);
3984 // Add Attribute - create with failure
3985 iErr
= HFS_fsOps
.fsops_setxattr(TestFile
, pcAttr
, pcData2
, strlen(pcData2
)+1, UVFSXattrHowCreate
);
3986 if ( iErr
!= EEXIST
)
3988 printf("SetAttr err [%d]\n", iErr
);
3992 // Add Attribute - set
3993 iErr
= HFS_fsOps
.fsops_setxattr(TestFile
, pcAttr
, pcData2
, strlen(pcData2
)+1, UVFSXattrHowSet
);
3996 printf("SetAttr err [%d]\n", iErr
);
4000 // Add Attribute - replace
4001 iErr
= HFS_fsOps
.fsops_setxattr(TestFile
, pcAttr
, pcData
, strlen(pcData
)+1, UVFSXattrHowReplace
);
4004 printf("SetAttr err [%d]\n", iErr
);
4008 // Add Attribute - replace with failure
4009 iErr
= HFS_fsOps
.fsops_setxattr(TestFile
, pcAttr2
, pcData
, strlen(pcData
)+1, UVFSXattrHowReplace
);
4010 if ( iErr
!= ENOATTR
)
4012 printf("SetAttr err [%d]\n", iErr
);
4016 // Add Attribute - remove
4017 iErr
= HFS_fsOps
.fsops_setxattr(TestFile
, pcAttr
, pcData
, strlen(pcData
)+1, UVFSXattrHowRemove
);
4020 printf("SetAttr err [%d]\n", iErr
);
4024 // Add Attribute - remove with failure
4025 iErr
= HFS_fsOps
.fsops_setxattr(TestFile
, pcAttr
, pcData
, strlen(pcData
)+1, UVFSXattrHowRemove
);
4026 if ( iErr
!= ENOATTR
)
4028 printf("SetAttr err [%d]\n", iErr
);
4032 // Get Attribute - check nothing left
4033 size_t actual_size
= INT32_MAX
;
4034 iErr
= HFS_fsOps
.fsops_listxattr(TestFile
, NULL
, 0, &actual_size
);
4035 if ( iErr
|| (actual_size
!= 0))
4037 printf("ListAttr err [%d]\n", iErr
);
4041 // Add Attribute - create extended attribute and check content
4042 const char * pcAttr3
= "com.apple.test.set3";
4043 uint8_t *pBuffer
= NULL
;
4044 uint8_t *pBufferRet
= NULL
;
4046 // Test more than one sector and ending outside boundary.
4047 #define ATTR_EXT_SIZE (5000)
4049 pBuffer
= malloc(ATTR_EXT_SIZE
);
4050 pBufferRet
= malloc(ATTR_EXT_SIZE
);
4052 if ( pBuffer
== NULL
|| pBufferRet
== NULL
)
4058 for (int i
= 0; i
< ATTR_EXT_SIZE
; ++i
)
4060 pBuffer
[i
] = i
% 256;
4061 pBufferRet
[i
] = 0xff;
4064 iErr
= HFS_fsOps
.fsops_setxattr(TestFile
, pcAttr3
, pBuffer
, ATTR_EXT_SIZE
, UVFSXattrHowCreate
);
4067 printf("SetAttr err [%d]\n", iErr
);
4071 iErr
= HFS_fsOps
.fsops_getxattr(TestFile
, pcAttr3
, pBufferRet
, ATTR_EXT_SIZE
, &actual_size
);
4074 printf("GetAttr err [%d]\n", iErr
);
4079 assert(actual_size
== ATTR_EXT_SIZE
);
4081 for (int i
= 0; i
< ATTR_EXT_SIZE
; ++i
)
4083 assert(pBuffer
[i
] == pBufferRet
[i
]);
4086 iErr
= HFS_fsOps
.fsops_setxattr(TestFile
, pcAttr3
, pBuffer
, ATTR_EXT_SIZE
, UVFSXattrHowRemove
);
4089 printf("SetAttr err [%d]\n", iErr
);
4098 // Reclaim test file
4099 HFS_fsOps
.fsops_reclaim(TestFile
);
4106 HFSTest_ListXattr( UVFSFileNode RootNode
)
4110 UVFSFileNode TestFile
= NULL
;
4111 iErr
= HFS_fsOps
.fsops_lookup( RootNode
, "kl.test", &TestFile
);
4114 printf("Lookup err [%d]\n", iErr
);
4118 // Get required size
4119 size_t actual_size
= 0;
4120 iErr
= HFS_fsOps
.fsops_listxattr(TestFile
, NULL
, 0, &actual_size
);
4123 printf("ListAttr err [%d]\n", iErr
);
4128 size_t size
= actual_size
;
4129 char *pcBuffer
= malloc(size
);
4130 if ( pcBuffer
== NULL
)
4137 iErr
= HFS_fsOps
.fsops_listxattr(TestFile
, pcBuffer
, size
, &actual_size
);
4140 printf("ListAttr err [%d]\n", iErr
);
4145 assert(actual_size
== size
);
4147 // Print Attributes Names
4148 size_t attr_size
= 0;
4149 char *pcAttribues
= pcBuffer
;
4151 while (attr_size
< size
)
4153 // Get required size
4155 iErr
= HFS_fsOps
.fsops_getxattr(TestFile
, pcAttribues
, NULL
, 0, &actual_size
);
4158 printf("GetAttr size err [%d]\n", iErr
);
4163 size_t bufsize
= actual_size
+1;
4164 char *pcAttrBuffer
= malloc(bufsize
);
4165 if ( pcAttrBuffer
== NULL
)
4170 bzero(pcAttrBuffer
, bufsize
);
4172 HFS_fsOps
.fsops_getxattr(TestFile
, pcAttribues
, pcAttrBuffer
, bufsize
, &actual_size
);
4175 printf("GetAttr err [%d]\n", iErr
);
4180 printf("Found attribute '%s' : %s\n", pcAttribues
, pcAttrBuffer
);
4184 size_t curr_attr_size
= strlen(pcAttribues
) + 1;
4186 attr_size
+= curr_attr_size
;
4187 pcAttribues
+= curr_attr_size
;
4194 // Reclaim test file
4195 HFS_fsOps
.fsops_reclaim(TestFile
);
4201 * Tests List Struct.
4205 #define ADD_TEST_WITH_CRASH_ABORT(testName, dmgPath, testHandler, CrashAbortType, CrashAbortCallback, CrashAbortCount) \
4206 { .pcTestName = testName, .pcDMGPath = dmgPath, .pfTestHandler = testHandler, \
4207 .eCrashID = CrashAbortType, .pAbortFunc = CrashAbortCallback, \
4208 .uCrashAbortCnt = CrashAbortCount \
4212 #define ADD_TEST(testName, dmgPath, testHandler) \
4213 { .pcTestName = testName, .pcDMGPath = dmgPath, .pfTestHandler = testHandler, \
4216 #define ADD_TEST_NO_SYNC(testName, dmgPath, testHandler) \
4217 { .pcTestName = testName, .pcDMGPath = dmgPath, .pfTestHandler = testHandler, \
4220 TestData_S gsTestsData
[] = {
4221 #if 1 // Enable non-journal tests
4222 ADD_TEST( "HFSTest_JustMount", "/Volumes/SSD_Shared/FS_DMGs/HFSEmpty.dmg", &HFSTest_JustMount
),
4223 ADD_TEST( "HFSTest_ReadDefragmentFile", "/Volumes/SSD_Shared/FS_DMGs/HFSDeFragment.dmg", &HFSTest_ReadDefragmentFile
),
4224 ADD_TEST( "HFSTest_RemoveDir", "/Volumes/SSD_Shared/FS_DMGs/HFSRemoveDir.dmg", &HFSTest_RemoveDir
),
4225 ADD_TEST( "HFSTest_Remove", "/Volumes/SSD_Shared/FS_DMGs/HFSRemove.dmg", &HFSTest_Remove
),
4226 ADD_TEST( "HFSTest_ReadDir", "/Volumes/SSD_Shared/FS_DMGs/HFSReadDir.dmg", &HFSTest_ReadDir
),
4227 ADD_TEST( "HFSTest_ReadDirAttr", "/Volumes/SSD_Shared/FS_DMGs/HFSReadDir.dmg", &HFSTest_ReadDirAttr
),
4228 ADD_TEST( "HFSTest_MakeDir", "/Volumes/SSD_Shared/FS_DMGs/HFSEmpty.dmg", &HFSTest_MakeDir
),
4229 ADD_TEST( "HFSTest_SetAttr", "/Volumes/SSD_Shared/FS_DMGs/HFSSetAttr.dmg", &HFSTest_SetAttr
),
4230 ADD_TEST( "HFSTest_ReadSymLink", "/Volumes/SSD_Shared/FS_DMGs/HFSReadSymLink.dmg", &HFSTest_ReadSymlink
),
4231 ADD_TEST( "HFSTest_GetFSAttr", "/Volumes/SSD_Shared/FS_DMGs/HFSEmpty.dmg", &HFSTest_GetFSAttr
),
4232 ADD_TEST( "HFSTest_Create", "/Volumes/SSD_Shared/FS_DMGs/HFSEmpty.dmg", &HFSTest_Create
),
4233 ADD_TEST( "HFSTest_Symlink", "/Volumes/SSD_Shared/FS_DMGs/HFSEmpty.dmg", &HFSTest_Symlink
),
4234 ADD_TEST( "HFSTest_SymlinkOnFile", "/Volumes/SSD_Shared/FS_DMGs/HFSEmpty.dmg", &HFSTest_SymlinkOnFile
),
4235 ADD_TEST( "HFSTest_Rename", "/Volumes/SSD_Shared/FS_DMGs/HFSEmpty.dmg", &HFSTest_Rename
),
4236 ADD_TEST( "HFSTest_WriteRead", "/Volumes/SSD_Shared/FS_DMGs/HFSEmpty.dmg", &HFSTest_WriteRead
),
4237 ADD_TEST( "HFSTest_RandomIO", "/Volumes/SSD_Shared/FS_DMGs/HFS100MB.dmg", &HFSTest_RandomIO
),
4238 ADD_TEST( "HFSTest_Create1000Files", "/Volumes/SSD_Shared/FS_DMGs/HFSEmpty.dmg", &HFSTest_Create1000Files
),
4239 ADD_TEST( "HFSTest_HardLink", "/Volumes/SSD_Shared/FS_DMGs/HFSHardLink.dmg", &HFSTest_HardLink
),
4240 ADD_TEST( "HFSTest_CreateHardLink", "/Volumes/SSD_Shared/FS_DMGs/HFSEmpty.dmg", &HFSTest_CreateHardLink
),
4241 ADD_TEST( "HFSTest_RenameToHardlink", "/Volumes/SSD_Shared/FS_DMGs/HFSEmpty.dmg", &HFSTest_RenameToHardlink
),
4242 ADD_TEST( "HFSTest_SetXattr", "/Volumes/SSD_Shared/FS_DMGs/HFSXattr.dmg", &HFSTest_SetXattr
),
4243 ADD_TEST( "HFSTest_ListXattr", "/Volumes/SSD_Shared/FS_DMGs/HFSXattr.dmg", &HFSTest_ListXattr
),
4244 ADD_TEST( "HFSTest_RootFillUp", "/Volumes/SSD_Shared/FS_DMGs/HFSEmpty.dmg", &HFSTest_RootFillUp
),
4245 ADD_TEST( "HFSTest_ScanDir", "/Volumes/SSD_Shared/FS_DMGs/HFSEmpty.dmg", &HFSTest_ScanDir
),
4246 ADD_TEST( "HFSTest_MultiThreadedRW", CREATE_HFS_DMG
, &HFSTest_MultiThreadedRW_wJournal
),
4247 ADD_TEST_NO_SYNC( "HFSTest_ValidateUnmount", "/Volumes/SSD_Shared/FS_DMGs/HFSEmpty.dmg", &HFSTest_ValidateUnmount
),
4248 ADD_TEST( "HFSTest_ScanID", "/Volumes/SSD_Shared/FS_DMGs/HFSEmpty.dmg", &HFSTest_ScanID
),
4250 #if 1 // Enbale journal-tests
4251 ADD_TEST( "HFSTest_OpenJournal", "/Volumes/SSD_Shared/FS_DMGs/HFSJ-Empty.dmg", &HFSTest_OpenJournal
),
4252 ADD_TEST( "HFSTest_WriteToJournal", "/Volumes/SSD_Shared/FS_DMGs/HFSJ-Empty.dmg", &HFSTest_WriteToJournal
),
4253 ADD_TEST( "HFSTest_JustMount_wJournal", "/Volumes/SSD_Shared/FS_DMGs/HFSJ-Empty.dmg", &HFSTest_JustMount
),
4254 ADD_TEST( "HFSTest_ReadDefragmentFile_wJournal", "/Volumes/SSD_Shared/FS_DMGs/HFSJ-DeFragment.dmg", &HFSTest_ReadDefragmentFile
),
4255 ADD_TEST( "HFSTest_RemoveDir_wJournal", "/Volumes/SSD_Shared/FS_DMGs/HFSJ-RemoveDir.dmg", &HFSTest_RemoveDir
),
4256 ADD_TEST( "HFSTest_Remove_wJournal", "/Volumes/SSD_Shared/FS_DMGs/HFSJ-Remove.dmg", &HFSTest_Remove
),
4257 ADD_TEST( "HFSTest_ReadDir_wJournal", "/Volumes/SSD_Shared/FS_DMGs/HFSJ-ReadDir.dmg", &HFSTest_ReadDir
),
4258 ADD_TEST( "HFSTest_ReadDirAttr_wJournal", "/Volumes/SSD_Shared/FS_DMGs/HFSJ-ReadDir.dmg", &HFSTest_ReadDirAttr
),
4259 ADD_TEST( "HFSTest_MakeDir_wJournal", "/Volumes/SSD_Shared/FS_DMGs/HFSJ-Empty.dmg", &HFSTest_MakeDir
),
4260 ADD_TEST( "HFSTest_SetAttr_wJournal", "/Volumes/SSD_Shared/FS_DMGs/HFSJ-SetAttr.dmg", &HFSTest_SetAttr
),
4261 ADD_TEST( "HFSTest_ReadSymLink_wJournal", "/Volumes/SSD_Shared/FS_DMGs/HFSJ-ReadSymLink.dmg", &HFSTest_ReadSymlink
),
4262 ADD_TEST( "HFSTest_GetFSAttr_wJournal", "/Volumes/SSD_Shared/FS_DMGs/HFSJ-Empty.dmg", &HFSTest_GetFSAttr
),
4263 ADD_TEST( "HFSTest_Create_wJournal", "/Volumes/SSD_Shared/FS_DMGs/HFSJ-Empty.dmg", &HFSTest_Create
),
4264 ADD_TEST( "HFSTest_Symlink_wJournal", "/Volumes/SSD_Shared/FS_DMGs/HFSJ-Empty.dmg", &HFSTest_Symlink
),
4265 ADD_TEST( "HFSTest_SymlinkOnFile", "/Volumes/SSD_Shared/FS_DMGs/HFSEmpty.dmg", &HFSTest_SymlinkOnFile
),
4266 ADD_TEST( "HFSTest_Rename_wJournal", "/Volumes/SSD_Shared/FS_DMGs/HFSJ-Empty.dmg", &HFSTest_Rename
),
4267 ADD_TEST( "HFSTest_WriteRead_wJournal", "/Volumes/SSD_Shared/FS_DMGs/HFSJ-Empty.dmg", &HFSTest_WriteRead
),
4268 ADD_TEST( "HFSTest_RandomIO_wJournal", "/Volumes/SSD_Shared/FS_DMGs/HFSJ-144MB.dmg", &HFSTest_RandomIO
),
4269 ADD_TEST( "HFSTest_Create1000Files_wJournal", "/Volumes/SSD_Shared/FS_DMGs/HFSJ-EmptyLarge.dmg", &HFSTest_Create1000Files
),
4270 ADD_TEST( "HFSTest_HardLink_wJournal", "/Volumes/SSD_Shared/FS_DMGs/HFSJ-HardLink.dmg", &HFSTest_HardLink
),
4271 ADD_TEST( "HFSTest_CreateHardLink_wJournal", "/Volumes/SSD_Shared/FS_DMGs/HFSJ-EmptyLarge.dmg", &HFSTest_CreateHardLink
),
4272 ADD_TEST( "HFSTest_RootFillUp_wJournal", "/Volumes/SSD_Shared/FS_DMGs/HFSJ-EmptyLarge.dmg", &HFSTest_RootFillUp
),
4273 ADD_TEST( "HFSTest_MultiThreadedRW_wJournal", "", &HFSTest_MultiThreadedRW_wJournal
),
4274 ADD_TEST( "HFSTest_DeleteAHugeDefragmentedFile_wJournal", "", &HFSTest_DeleteAHugeDefragmentedFile_wJournal
),
4275 ADD_TEST( "HFSTest_CreateJournal_Sparse", CREATE_SPARSE_VOLUME
, &HFSTest_OpenJournal
),
4276 ADD_TEST( "HFSTest_MakeDirAndKeep_Sparse", CREATE_SPARSE_VOLUME
, &HFSTest_MakeDirAndKeep
),
4277 ADD_TEST( "HFSTest_CreateAndWriteToJournal_Sparse", CREATE_SPARSE_VOLUME
, &HFSTest_WriteToJournal
),
4278 ADD_TEST( "HFSTest_MultiThreadedRW_wJournal_Sparse", CREATE_SPARSE_VOLUME
, &HFSTest_MultiThreadedRW_wJournal
),
4279 ADD_TEST( "HFSTest_ScanDir", "/Volumes/SSD_Shared/FS_DMGs/HFSJ-Empty.dmg", &HFSTest_ScanDir
),
4280 ADD_TEST_NO_SYNC( "HFSTest_ValidateUnmount_wJournal", "/Volumes/SSD_Shared/FS_DMGs/HFSJ-Empty.dmg", &HFSTest_ValidateUnmount_wJournal
),
4281 ADD_TEST( "HFSTest_Corrupted2ndDiskImage", "/Volumes/SSD_Shared/FS_DMGs/corrupted_80M.dmg.sparseimage",
4282 &HFSTest_Corrupted2ndDiskImage
),
4283 ADD_TEST( "HFSTest_ScanID", "/Volumes/SSD_Shared/FS_DMGs/HFSJ-Empty.dmg", &HFSTest_ScanID
),
4287 // The following 2 tests checks mount after unmount, no-journal
4288 ADD_TEST_WITH_CRASH_ABORT( "HFSTest_OneSync", "/Volumes/SSD_Shared/FS_DMGs/HFSEmpty.dmg",
4289 &HFSTest_OneSync
, CRASH_ABORT_RANDOM
, HFSTest_SaveDMG
, 0 ),
4290 ADD_TEST( "HFSTest_ConfirmTestFolderExists", TEMP_DMG_BKUP
, &HFSTest_ConfirmTestFolderExists
),
4292 // The following 2 tests checks mount after unmount with journal
4293 ADD_TEST_WITH_CRASH_ABORT( "HFSTest_OneSync_wJournal", "/Volumes/SSD_Shared/FS_DMGs/HFSJ-Empty.dmg",
4294 &HFSTest_OneSync
, CRASH_ABORT_RANDOM
, HFSTest_SaveDMG
, 0 ),
4295 ADD_TEST( "HFSTest_ConfirmTestFolderExists", TEMP_DMG_BKUP
, &HFSTest_ConfirmTestFolderExists
),
4297 ADD_TEST_WITH_CRASH_ABORT("HFSTest_OpenJournal_wCrashOnMakeDir", "/Volumes/SSD_Shared/FS_DMGs/HFSJ-Empty.dmg",
4298 &HFSTest_OpenJournal
, CRASH_ABORT_MAKE_DIR
, HFSTest_FailTestOnCrashAbort
, 0),
4300 ADD_TEST_WITH_CRASH_ABORT("HFSTest_OpenJournal_wCrashAfterBlockData", "/Volumes/SSD_Shared/FS_DMGs/HFSJ-Empty.dmg",
4301 &HFSTest_OpenJournal
, CRASH_ABORT_JOURNAL_AFTER_BLOCK_DATA
, HFSTest_CrashAbort
, 0),
4303 ADD_TEST_WITH_CRASH_ABORT("HFSTest_OpenJournal_wCrashAfterJournalData", "/Volumes/SSD_Shared/FS_DMGs/HFSJ-Empty.dmg",
4304 &HFSTest_OpenJournal
, CRASH_ABORT_JOURNAL_AFTER_JOURNAL_DATA
, HFSTest_CrashAbort
, 0),
4306 ADD_TEST_WITH_CRASH_ABORT("HFSTest_OpenJournal_wCrashAfterJournalHeader", "/Volumes/SSD_Shared/FS_DMGs/HFSJ-Empty.dmg",
4307 &HFSTest_OpenJournal
, CRASH_ABORT_JOURNAL_AFTER_JOURNAL_HEADER
, HFSTest_CrashAbort
, 0),
4309 ADD_TEST_WITH_CRASH_ABORT("MultiThreadedRW_wJournal_RandomCrash", CREATE_SPARSE_VOLUME
,
4310 &MultiThreadedRW_wJournal_RandomCrash
, CRASH_ABORT_RANDOM
, HFSTest_CrashAbortAtRandom
, 0),
4312 // The following 2 tests check journal replay, make sure the drive is mountable, and the created fonder DOES exist
4313 ADD_TEST_WITH_CRASH_ABORT("HFSTest_MakeDirAndKeep_wCrashAfterJournalHeader", "/Volumes/SSD_Shared/FS_DMGs/HFSJ-Empty.dmg",
4314 &HFSTest_MakeDirAndKeep
, CRASH_ABORT_JOURNAL_AFTER_JOURNAL_HEADER
, HFSTest_CrashAbortOnMkDir
, 0),
4315 ADD_TEST( "HFSTest_ConfirmTestFolderExists", TEMP_DMG_BKUP
, &HFSTest_ConfirmTestFolderExists
),
4317 // The following 2 tests check journal replay, make sure the drive is mountable, and the created fonder does NOT exist
4318 ADD_TEST_WITH_CRASH_ABORT("HFSTest_MakeDirAndKeep_wCrashAfterJournalData", "/Volumes/SSD_Shared/FS_DMGs/HFSJ-Empty.dmg",
4319 &HFSTest_MakeDirAndKeep
, CRASH_ABORT_JOURNAL_AFTER_JOURNAL_DATA
, HFSTest_CrashAbortOnMkDir
, 0),
4320 ADD_TEST( "HFSTest_ConfirmTestFolderDoesntExists", TEMP_DMG_BKUP
, &HFSTest_ConfirmTestFolderDoesntExists
),
4322 // The following 2 tests check journal replay, make sure the drive is mountable, and the created fonder DOES exist
4323 ADD_TEST_WITH_CRASH_ABORT("HFSTest_MakeDirAndKeep_wCrashAfterJournalHeader_Sparse", CREATE_SPARSE_VOLUME
,
4324 &HFSTest_MakeDirAndKeep
, CRASH_ABORT_JOURNAL_AFTER_JOURNAL_HEADER
, HFSTest_CrashAbortOnMkDir
, 1),
4325 ADD_TEST( "HFSTest_ConfirmTestFolderExists", TEMP_DMG_BKUP_SPARSE
, &HFSTest_ConfirmTestFolderExists
),
4330 void *SyncerThread(void *pvArgs
) {
4333 TestData_S
*psTestData
= pvArgs
;
4335 printf("Syncer Thread runs every %u mS\n", guSyncerPeriod
);
4337 while(psTestData
->bSyncerOn
) {
4338 usleep(guSyncerPeriod
* 1000);
4339 iErr
= HFS_fsOps
.fsops_sync(psTestData
->psRootNode
);
4340 psTestData
->uSyncerCount
++;
4342 printf("fsops_sync returned %d\n", iErr
);
4347 TesterThreadReturnStatus_S
*psReturnStatus
= malloc(sizeof(TesterThreadReturnStatus_S
));
4348 assert(psReturnStatus
);
4349 memset(psReturnStatus
, 0, sizeof(*psReturnStatus
));
4351 printf("Syncer returns %d\n", iErr
);
4353 psReturnStatus
->iErr
= iErr
;
4355 return((void*)psReturnStatus
);
4358 static int KickOffSyncerThread(TestData_S
*psTestData
) {
4362 if (guSyncerPeriod
== 0) {
4365 psTestData
->bSyncerOn
= true;
4367 pthread_attr_t sAttr
;
4368 pthread_attr_init(&sAttr
);
4369 pthread_attr_setdetachstate(&sAttr
, PTHREAD_CREATE_JOINABLE
);
4371 iErr
= pthread_create(&psTestData
->sSyncerThread
, &sAttr
, SyncerThread
, psTestData
);
4373 pthread_attr_destroy(&sAttr
);
4379 static int ShutdownSyncerThread(TestData_S
*psTestData
) {
4382 TesterThreadReturnStatus_S
*psReturnStatus
= NULL
;
4384 if (guSyncerPeriod
== 0) {
4388 psTestData
->bSyncerOn
= false;
4389 iErr
= pthread_join(psTestData
->sSyncerThread
, (void*)&psReturnStatus
);
4391 printf("Error waiting for Syncer thread! %d\n", iErr
);
4395 printf("Syncer Thead ran %u times (iErr %d)\n", psTestData
->uSyncerCount
, iErr
);
4397 assert(psReturnStatus
);
4399 iErr
= psReturnStatus
->iErr
;
4401 printf("Syncer thread returned iErr = %d\n", iErr
);
4406 if (psReturnStatus
) {
4407 free(psReturnStatus
);
4413 static int HFSTest_RunTest(TestData_S
*psTestData
) {
4414 UVFSScanVolsRequest sScanVolsReq
= {0};
4415 UVFSScanVolsReply sScanVolsReply
= {0};
4417 int iFD
= HFSTest_PrepareEnv( psTestData
);
4420 iErr
= HFS_fsOps
.fsops_taste( iFD
);
4421 printf("Taste err [%d]\n",iErr
);
4424 HFSTest_DestroyEnv( iFD
);
4428 iErr
= HFS_fsOps
.fsops_scanvols( iFD
, &sScanVolsReq
, &sScanVolsReply
);
4429 printf("ScanVols err [%d]\n", iErr
);
4433 HFSTest_DestroyEnv( iFD
);
4437 UVFSFileNode RootNode
= NULL
;
4438 iErr
= HFS_fsOps
.fsops_mount( iFD
, sScanVolsReply
.sr_volid
, 0, NULL
, &RootNode
);
4439 printf("Mount err [%d]\n", iErr
);
4443 HFSTest_DestroyEnv( iFD
);
4447 psTestData
->psRootNode
= RootNode
;
4448 iErr
= KickOffSyncerThread(psTestData
);
4451 HFSTest_DestroyEnv( iFD
);
4456 iErr
= psTestData
->pfTestHandler( RootNode
);
4457 printf("Test [%s] finish with error code [%d]\n", psTestData
->pcTestName
, iErr
);
4459 if (psTestData
->eCrashID
== CRASH_ABORT_NONE
)
4463 HFSTest_DestroyEnv( iFD
);
4467 iErr
= ShutdownSyncerThread(psTestData
);
4470 HFSTest_DestroyEnv( iFD
);
4474 iErr
= HFS_fsOps
.fsops_unmount(RootNode
, UVFSUnmountHintNone
);
4475 printf("UnMount err [%d]\n", iErr
);
4478 HFSTest_DestroyEnv( iFD
);
4482 HFSTest_PrintCacheStats();
4485 if (psTestData
->eCrashID
!= CRASH_ABORT_NONE
) {
4487 // Execute post crash analysis
4488 iErr
= psTestData
->pAbortFunc(psTestData
,
4489 gsCrashReport
.eCrashID
,
4491 gsCrashReport
.psNode
,
4492 gsCrashReport
.pSyncerThread
);
4494 printf("Analysis [%s] finished with error code [%d]\n", psTestData
->pcTestName
, iErr
);
4497 HFSTest_DestroyEnv( iFD
);
4506 //assert(gCacheStat.buf_cache_size == 0);
4509 char pcFsckCmd
[512] = {0};
4510 strcat( pcFsckCmd
, "/System/Library/Filesystems/hfs.fs/Contents/Resources/fsck_hfs -fd /dev/disk");
4512 strcat( pcFsckCmd
, pcLastDevPathName
);
4513 if (pcDevNum
[0] != '\0') {
4514 strcat( pcFsckCmd
, "s" );
4515 strcat( pcFsckCmd
, pcDevNum
);
4517 printf("Execute %s\n", pcFsckCmd
);
4518 iErr
= system( pcFsckCmd
);
4521 printf( "*** Fsck CMD failed! (%d)\n", iErr
);
4522 HFSTest_DestroyEnv( iFD
);
4525 printf( "*** Fsck CMD succeeded!\n");
4528 HFSTest_DestroyEnv( iFD
);
4534 int HFSTest_CrashAbort_Hanlder(CrashAbort_E eAbort
, int iFD
, UVFSFileNode psNode
, pthread_t pSyncerThread
) {
4535 printf("HFSTest_CrashAbort_Hanlder (%u):\n", guCrashAbortCnt
);
4536 if (guCrashAbortCnt
) {
4541 close(iFD
); // prevent additional writes to media
4542 if (pSyncerThread
== pthread_self()) {
4543 printf("Crash Abort on Syncer Thread!\n");
4546 gsCrashReport
.uCrashCount
++;
4547 gsCrashReport
.eCrashID
= eAbort
;
4548 gsCrashReport
.iFD
= iFD
;
4549 gsCrashReport
.psNode
= psNode
;
4550 gsCrashReport
.pSyncerThread
= pSyncerThread
;
4557 int hfs_tester_run_fsck(void)
4560 int iErr
= HFS_fsOps
.fsops_init();
4561 printf("Init err [%d]\n",iErr
);
4565 TestData_S sTestData
= {
4566 .pcTestName
= "hfs_tester_run_fsck",
4567 .pcDMGPath
= "/Volumes/SSD_Shared/FS_DMGs/HFSJ-Empty.dmg",
4570 int iFD
= HFSTest_PrepareEnv(&sTestData
);
4572 iErr
= HFS_fsOps
.fsops_taste( iFD
);
4573 printf("Taste err [%d]\n",iErr
);
4576 HFSTest_DestroyEnv( iFD
);
4580 iErr
= HFS_fsOps
.fsops_check(iFD
, 0, NULL
, QUICK_CHECK
);
4581 printf("Check err [%d]\n",iErr
);
4586 HFSTest_DestroyEnv( iFD
);
4589 iErr
= HFS_fsOps
.fsops_init();
4590 printf("Init err [%d]\n",iErr
);
4594 sTestData
.pcDMGPath
= "/Volumes/SSD_Shared/FS_DMGs/HFSEmpty.dmg";
4596 iFD
= HFSTest_PrepareEnv(&sTestData
);
4598 iErr
= HFS_fsOps
.fsops_taste( iFD
);
4599 printf("Taste err [%d]\n",iErr
);
4602 HFSTest_DestroyEnv( iFD
);
4606 iErr
= HFS_fsOps
.fsops_check(iFD
, 0, NULL
, QUICK_CHECK
);
4607 printf("Check err [%d]\n",iErr
);
4612 HFSTest_DestroyEnv( iFD
);
4616 int hfs_tester_run(uint32_t uFirstTest
, uint32_t uLastTest
)
4618 uint32_t uTestRan
= 0;
4619 int iErr
= HFS_fsOps
.fsops_init();
4620 printf("Init err [%d]\n",iErr
);
4624 uint32_t uAvailTests
= sizeof(gsTestsData
)/sizeof(gsTestsData
[0]);
4626 (uLastTest
> uAvailTests
)) {
4628 uLastTest
= uAvailTests
;
4631 for ( unsigned uTestNum
=uFirstTest
; uTestNum
< uLastTest
; uTestNum
++ )
4633 printf("******************************************************************************************\n");
4634 printf("**** about to run test [%s] [%u] \n", gsTestsData
[uTestNum
].pcTestName
, uTestNum
);
4635 printf("******************************************************************************************\n");
4638 HFSTest_ClearCrashAbortFunctionArray();
4640 if (gsTestsData
[uTestNum
].eCrashID
) {
4641 // Inject Crach condition
4642 CrashAbort_E eCrashID
= gsTestsData
[uTestNum
].eCrashID
;
4643 printf( "Adding Crash-Abort Function at (%u), %s.\n", eCrashID
, ppcCrashAbortDesc
[eCrashID
] );
4644 guCrashAbortCnt
= gsTestsData
[uTestNum
].uCrashAbortCnt
;
4645 gpsCrashAbortFunctionArray
[eCrashID
] = HFSTest_CrashAbort_Hanlder
;
4646 memset(&gsCrashReport
, 0, sizeof(gsCrashReport
));
4650 iErr
= HFSTest_RunTest(&gsTestsData
[uTestNum
]);
4658 HFS_fsOps
.fsops_fini();
4660 printf("*** Run %u out of %u tests successfully\n", uTestRan
, uAvailTests
);
4665 /*******************************************/
4666 /*******************************************/
4667 /*******************************************/
4668 // Predefined Tests END.
4669 /*******************************************/
4670 /*******************************************/
4671 /*******************************************/
4672 int main( int argc
, const char * argv
[] ) {
4673 uint32_t uFirstTest
= 0;
4674 uint32_t uLastTest
= 0;
4676 time_t sTimeStamp
= time(NULL
);
4677 char pcTimeStamp
[256] = {0};
4678 strcpy(pcTimeStamp
, ctime(&sTimeStamp
));
4679 pcTimeStamp
[strlen(pcTimeStamp
)-1] = '\0'; // remove \n
4680 sprintf(gpcResultsFolder
, "\"/tmp/%s\"", pcTimeStamp
);
4681 printf("*** gpcResultsFolder is %s\n", gpcResultsFolder
);
4684 if ((argc
< 2) || (argc
> 5))
4686 printf("Usage : livefiles_hfs_tester < dev-path / RUN_HFS_TESTS > [First Test] [Last Test] [Syncer Period (mS)]\n");
4690 printf( "livefiles_hfs_tester %s (%u)\n", argv
[1], uFirstTest
);
4693 sscanf(argv
[2], "%u", &uFirstTest
);
4697 sscanf(argv
[3], "%u", &uLastTest
);
4701 sscanf(argv
[4], "%u", &guSyncerPeriod
);
4704 if ( strncmp(argv
[1], HFS_TEST_PREFIX
, strlen(HFS_TEST_PREFIX
)) == 0 )
4706 int err
= hfs_tester_run(uFirstTest
, uLastTest
);
4707 printf("*** hfs_tester_run return status : %d ***\n", err
);
4708 if (err
>= 256) err
= -1; // exit code overflow
4711 } else if ( strncmp(argv
[1], HFS_RUN_FSCK
, strlen(HFS_RUN_FSCK
)) == 0 )
4713 int err
= hfs_tester_run_fsck();
4714 printf("*** hfs_tester_run_fsck return status : %d ***\n", err
);
4715 if (err
>= 256) err
= -1; // exit code overflow
4719 UVFSScanVolsRequest sScanVolsReq
= {0};
4720 UVFSScanVolsReply sScanVolsReply
= {0};
4722 int fd
= open( argv
[1], O_RDWR
);
4723 int uCycleCounter
= 0;
4725 UVFSFileNode RootNode
= NULL
;
4728 printf("Failed to open [%s] errno %d\n", argv
[1], errno
);
4735 err
= HFS_fsOps
.fsops_init();
4736 printf("Init err [%d]\n",err
);
4739 err
= HFS_fsOps
.fsops_taste(fd
);
4740 printf("Taste err [%d]\n",err
);
4743 err
= HFS_fsOps
.fsops_scanvols(fd
, &sScanVolsReq
, &sScanVolsReply
);
4744 printf("ScanVols err [%d]\n",err
);
4747 err
= HFS_fsOps
.fsops_mount(fd
, sScanVolsReply
.sr_volid
, 0, NULL
, &RootNode
);
4748 printf("Mount err [%d]\n",err
);
4751 ReadDirAttr(RootNode
,NULL
, 0);
4753 UVFSFileNode D1_Node
= NULL
;
4754 err
= CreateNewFolder(RootNode
,&D1_Node
,"D1");
4755 printf("CreateNewFolder err [%d]\n",err
);
4758 bool bFound
= false;
4759 read_directory_and_search_for_name( RootNode
, "D1", &bFound
, NULL
, 0);
4762 printf("Dir read failed, D1 wasn't found in Root");
4766 HFS_fsOps
.fsops_reclaim(D1_Node
);
4769 err
= RemoveFolder(RootNode
,"D1");
4770 printf("Remove Folder D1 from Root err [%d]\n",err
);
4774 }while(uCycleCounter
< TEST_CYCLE_COUNT
);
4776 err
= HFS_fsOps
.fsops_unmount(RootNode
, UVFSUnmountHintNone
);
4777 printf("UnMount err [%d]\n",err
);