1 /* This FileX test concentrates on recovery operation when there are duplicate entries.  */
2 
3 #ifndef FX_STANDALONE_ENABLE
4 #include   "tx_api.h"
5 #endif
6 #include   "fx_api.h"
7 #include   "fx_directory.h"
8 #include   "fx_ram_driver_test.h"
9 #include   "fx_fault_tolerant.h"
10 #include   "fx_utility.h"
11 #include   <stdio.h>
12 
13 #define     DEMO_STACK_SIZE         4096
14 #define     CACHE_SIZE              16*128
15 #ifdef FX_ENABLE_FAULT_TOLERANT
16 #define     FAULT_TOLERANT_SIZE     FX_FAULT_TOLERANT_MINIMAL_BUFFER_SIZE
17 #else
18 #define     FAULT_TOLERANT_SIZE     0
19 #endif
20 
21 #define     DIRECTORY_NAME          "DUP_DIR"
22 #define     FILE_NAME               "abc"
23 
24 
25 /* Define the ThreadX and FileX object control blocks...  */
26 
27 #ifndef FX_STANDALONE_ENABLE
28 static TX_THREAD                ftest_0;
29 #endif
30 static FX_MEDIA                 ram_disk;
31 static CHAR                     name[256];
32 
33 /* Define the counters used in the test application...  */
34 
35 #ifndef FX_STANDALONE_ENABLE
36 static UCHAR                    ram_disk_memory[1024 * 1024];
37 static UCHAR                    *cache_buffer;
38 static UCHAR                    *fault_tolerant_buffer;
39 #else
40 static UCHAR                    cache_buffer[CACHE_SIZE];
41 static UCHAR                    fault_tolerant_buffer[FAULT_TOLERANT_SIZE];
42 #endif
43 
44 extern ULONG   _fx_ram_driver_copy_default_format;
45 
46 
47 /* Define thread prototypes.  */
48 
49 void    filex_directory_duplicate_entries_application_define(void *first_unused_memory);
50 static void    ftest_0_entry(ULONG thread_input);
51 
52 VOID  _fx_ram_driver(FX_MEDIA *media_ptr);
53 void  test_control_return(UINT status);
54 
55 
56 
57 
58 /* Define what the initial system looks like.  */
59 
60 #ifdef CTEST
test_application_define(void * first_unused_memory)61 void test_application_define(void *first_unused_memory)
62 #else
63 void    filex_directory_duplicate_entries_application_define(void *first_unused_memory)
64 #endif
65 {
66 
67 #ifndef FX_STANDALONE_ENABLE
68 UCHAR    *pointer;
69 
70 
71     /* Setup the working pointer.  */
72     pointer =  (UCHAR *) first_unused_memory;
73 
74     /* Create the main thread.  */
75     tx_thread_create(&ftest_0, "thread 0", ftest_0_entry, 0,
76             pointer, DEMO_STACK_SIZE,
77             4, 4, TX_NO_TIME_SLICE, TX_AUTO_START);
78 
79     pointer =  pointer + DEMO_STACK_SIZE;
80 
81     /* Setup memory for the RAM disk and the sector cache.  */
82     cache_buffer =  pointer;
83     pointer =  pointer + CACHE_SIZE;
84     fault_tolerant_buffer = pointer;
85     pointer += FAULT_TOLERANT_SIZE;
86 
87 #endif
88 
89     /* Initialize the FileX system.  */
90     fx_system_initialize();
91 #ifdef FX_STANDALONE_ENABLE
92     ftest_0_entry(0);
93 #endif
94 }
95 
delete_duplicate_entry(FX_MEDIA * media_ptr,CHAR * parent_directory,CHAR * duplicate_entry_name)96 static void    delete_duplicate_entry(FX_MEDIA *media_ptr,
97                                       CHAR *parent_directory,
98                                       CHAR *duplicate_entry_name)
99 {
100 FX_DIR_ENTRY    dir_entry;
101 
102     fx_directory_default_set(media_ptr, parent_directory);
103 
104     /* Get the dir entry of DIRECTORY_NAME. */
105     FX_PROTECT
106 
107     dir_entry.fx_dir_entry_name =  media_ptr -> fx_media_name_buffer + FX_MAX_LONG_NAME_LEN;
108     dir_entry.fx_dir_entry_short_name[0] =  0;
109     _fx_directory_search(media_ptr, duplicate_entry_name, &dir_entry, FX_NULL, FX_NULL);
110 
111     /* Now try to remove one of the duplicate dir entries. */
112     dir_entry.fx_dir_entry_name[0] =  (CHAR)FX_DIR_ENTRY_FREE;
113     dir_entry.fx_dir_entry_short_name[0] =  (CHAR)FX_DIR_ENTRY_FREE;
114     {
115         _fx_directory_entry_write(media_ptr, &dir_entry);
116     }
117     FX_UNPROTECT
118 }
119 
120 
121 /* Define the test threads.  */
122 
ftest_0_entry(ULONG thread_input)123 static void    ftest_0_entry(ULONG thread_input)
124 {
125 
126 UINT            status;
127 FX_DIR_ENTRY    dir_entry;
128 FX_MEDIA       *media_ptr = &ram_disk;
129 
130     FX_PARAMETER_NOT_USED(thread_input);
131 
132     /* Print out some test information banners.  */
133     printf("FileX Test:   Directory duplicate entries test.......................");
134 
135     /* Format the media.  This needs to be done before opening it!  */
136     status =  fx_media_format(&ram_disk,
137                             _fx_ram_driver,         // Driver entry
138                             ram_disk_memory,        // RAM disk memory pointer
139                             cache_buffer,           // Media buffer pointer
140                             CACHE_SIZE,             // Media buffer size
141                             "MY_RAM_DISK",          // Volume Name
142                             1,                      // Number of FATs
143                             32,                     // Directory Entries
144                             0,                      // Hidden sectors
145 
146 /* We need a larger disk to test the feature of fault tolerant. */
147 #ifdef FX_ENABLE_FAULT_TOLERANT
148                             512 * 8,                // Total sectors
149                             256,                    // Sector size
150                             8,                      // Sectors per cluster
151 #else
152                             512,                    // Total sectors
153                             128,                    // Sector size
154                             1,                      // Sectors per cluster
155 #endif
156 
157                             1,                      // Heads
158                             1);                     // Sectors per track
159     return_if_fail( status == FX_SUCCESS);
160 
161     /* Open the ram_disk.  */
162     status =  fx_media_open(&ram_disk, "RAM DISK", _fx_ram_driver, ram_disk_memory, cache_buffer, CACHE_SIZE);
163     return_if_fail( status == FX_SUCCESS);
164 
165 /* We need a larger disk to test the feature of fault tolerant. */
166 #ifdef FX_ENABLE_FAULT_TOLERANT
167     /* Enable fault tolerant if FX_ENABLE_FAULT_TOLERANT is defined. */
168     status = fx_fault_tolerant_enable(&ram_disk, fault_tolerant_buffer, FAULT_TOLERANT_SIZE);
169     return_if_fail( status == FX_SUCCESS);
170 #endif
171 
172     /* Create a directory.  */
173     status =  fx_directory_create(&ram_disk, DIRECTORY_NAME);
174     return_if_fail( status == FX_SUCCESS);
175 
176     status =  fx_directory_default_set(&ram_disk, DIRECTORY_NAME);
177     return_if_fail( status == FX_SUCCESS);
178 
179     /* Create a file in subdirectory. */
180     status =  fx_file_create(&ram_disk, FILE_NAME);
181     return_if_fail( status == FX_SUCCESS);
182 
183     status =  fx_directory_default_set(&ram_disk, "/");
184     return_if_fail( status == FX_SUCCESS);
185 
186     /* Get the dir entry of DIRECTORY_NAME. */
187     FX_PROTECT
188     dir_entry.fx_dir_entry_name =  ram_disk.fx_media_name_buffer + FX_MAX_LONG_NAME_LEN;
189     dir_entry.fx_dir_entry_short_name[0] =  0;
190     status =  _fx_directory_search(&ram_disk, DIRECTORY_NAME, &dir_entry, FX_NULL, FX_NULL);
191     return_if_fail( status == FX_SUCCESS);
192 
193     /* Duplicate the dir entry. */
194     dir_entry.fx_dir_entry_byte_offset += FX_DIR_ENTRY_SIZE;
195     {
196         status =  _fx_directory_entry_write(&ram_disk, &dir_entry);
197     }
198     return_if_fail( status == FX_SUCCESS);
199     FX_UNPROTECT
200 
201     /* Make sure there are duplicate dir entries. */
202     status =  fx_directory_first_entry_find(&ram_disk, name);
203     return_if_fail( status == FX_SUCCESS);
204     return_if_fail( strcmp(name, DIRECTORY_NAME) == 0);
205 
206     status =  fx_directory_next_entry_find(&ram_disk, name);
207     return_if_fail( status == FX_SUCCESS);
208     return_if_fail( strcmp(name, DIRECTORY_NAME) == 0);
209 
210     delete_duplicate_entry(&ram_disk, "/", DIRECTORY_NAME);
211 
212     /* Make sure there are no duplicate dir entries. */
213     status =  fx_directory_first_entry_find(&ram_disk, name);
214     return_if_fail( status == FX_SUCCESS);
215     return_if_fail( strcmp(name, DIRECTORY_NAME) == 0);
216 
217     status =  fx_directory_next_entry_find(&ram_disk, name);
218     return_if_fail( status != FX_SUCCESS);
219 
220     /* Check the file in DIRECTORY_NAME is still valid. */
221     status =  fx_directory_default_set(&ram_disk, DIRECTORY_NAME);
222     return_if_fail( status == FX_SUCCESS);
223 
224     /* Skip '.' and '..'. */
225     status =  fx_directory_first_entry_find(&ram_disk, name);
226     return_if_fail( status == FX_SUCCESS);
227     status =  fx_directory_next_entry_find(&ram_disk, name);
228     return_if_fail( status == FX_SUCCESS);
229 
230     /* Check the filename. */
231     status =  fx_directory_next_entry_find(&ram_disk, name);
232     return_if_fail( status == FX_SUCCESS);
233     return_if_fail( strcmp(name, FILE_NAME) == 0);
234 
235     /* Close the media.  */
236     status =  fx_media_close(&ram_disk);
237 
238     /* Determine if the test was successful.  */
239     if (status != FX_SUCCESS)
240     {
241 
242         printf("ERROR!\n");
243         test_control_return(254);
244     }
245     else
246     {
247 
248         printf("SUCCESS!\n");
249         test_control_return(0);
250     }
251 }
252