OpenCores
URL https://opencores.org/ocsvn/mlite/mlite/trunk

Subversion Repositories mlite

[/] [mlite/] [trunk/] [kernel/] [filesys.c] - Blame information for rev 307

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 219 rhoads
/*--------------------------------------------------------------------
2
 * TITLE: Plasma File System
3
 * AUTHOR: Steve Rhoads (rhoadss@yahoo.com)
4
 * DATE CREATED: 4/26/07
5
 * FILENAME: filesys.c
6
 * PROJECT: Plasma CPU core
7
 * COPYRIGHT: Software placed into the public domain by the author.
8
 *    Software 'as is' without warranty.  Author liable for nothing.
9
 * DESCRIPTION:
10
 *    Plasma File System.  Supports RAM, flash, and disk file systems.
11
 *    Possible call tree:
12
 *      OS_fclose()
13
 *        FileFindRecursive()      //find the existing file
14
 *          FileOpen()             //open root file system
15
 *          FileFind()             //find the next level of directory
16
 *            OS_fread()           //read the directory file
17
 *              BlockRead()        //read blocks of directory
18
 *                MediaBlockRead() //low level read
19
 *          FileOpen()             //open next directory
20
 *        OS_fwrite()              //write file entry into directory
21
 *        BlockRead()              //flush changes to directory
22
 *--------------------------------------------------------------------*/
23 302 rhoads
#ifdef WIN32
24 219 rhoads
#include <stdio.h>
25
#include <stdlib.h>
26
#include <string.h>
27 302 rhoads
#define  _LIBC
28 219 rhoads
#endif
29 302 rhoads
#include "rtos.h"
30 219 rhoads
 
31 305 rhoads
#define FLASH_SIZE        1024*1024*16
32
#define FLASH_SECTOR_SIZE 1024*128
33
#define FLASH_BLOCK_SIZE  512
34
#define FLASH_LN2_SIZE    9                  //2^FLASH_LN2_SIZE == FLASH_BLOCK_SIZE
35
#define FLASH_OFFSET      FLASH_SECTOR_SIZE  //offset to start of flash file system
36 219 rhoads
 
37 305 rhoads
#define BLOCK_SIZE        512
38
#define FILE_NAME_SIZE    40
39
#define FULL_NAME_SIZE    128
40
#define BLOCK_MALLOC      0x0
41
#define BLOCK_EOF         0xffffffff
42
 
43 219 rhoads
typedef enum {
44
   FILE_MEDIA_RAM,
45
   FILE_MEDIA_FLASH,
46
   FILE_MEDIA_DISK
47
} OS_MediaType_e;
48
 
49
typedef struct OS_FileEntry_s {
50
   char name[FILE_NAME_SIZE];
51
   uint32 blockIndex;       //first block of file
52
   uint32 modifiedTime;
53
   uint32 length;
54
   uint8 isDirectory;
55
   uint8 attributes;
56
   uint8 valid;
57
   uint8 mediaType;
58
   uint16 blockSize;        //Normally BLOCK_SIZE
59
} OS_FileEntry_t;
60
 
61
typedef struct OS_Block_s {
62
   uint32 next;
63
   uint8 data[4];
64
} OS_Block_t;
65
 
66
struct OS_FILE_s {
67
   OS_FileEntry_t fileEntry;  //written to directory upon OS_fclose()
68
   uint8 fileModified;
69
   uint8 blockModified;
70
   uint32 blockIndex;         //index of block
71
   uint32 blockOffset;        //byte offset into block
72
   uint32 fileOffset;         //byte offset into file
73
   char fullname[FULL_NAME_SIZE]; //includes full path
74
   OS_Block_t *block;
75
   OS_Block_t *blockLocal;    //local copy for flash or disk file system
76
};
77
 
78
static OS_FileEntry_t rootFileEntry;
79 302 rhoads
static OS_Mutex_t *mutexFilesys;
80 219 rhoads
 
81
// Public prototypes
82
#ifndef _FILESYS_
83
typedef struct OS_FILE_s OS_FILE;
84
#endif
85
OS_FILE *OS_fopen(char *name, char *mode);
86
void OS_fclose(OS_FILE *file);
87
int OS_fread(void *buffer, int size, int count, OS_FILE *file);
88
int OS_fwrite(void *buffer, int size, int count, OS_FILE *file);
89
int OS_fseek(OS_FILE *file, int offset, int mode);
90
int OS_fmkdir(char *name);
91
int OS_fdir(OS_FILE *dir, char name[64]);
92
void OS_fdelete(char *name);
93
 
94
 
95
/***************** Media Functions Start ***********************/
96 302 rhoads
#ifdef INCLUDE_FLASH
97 305 rhoads
#define FLASH_BLOCKS FLASH_SIZE/FLASH_BLOCK_SIZE
98
#define FLASH_START  (FLASH_OFFSET+FLASH_BLOCKS/8*2)/FLASH_BLOCK_SIZE
99 302 rhoads
static unsigned char FlashBlockEmpty[FLASH_BLOCKS/8];
100
static unsigned char FlashBlockUsed[FLASH_BLOCKS/8];
101 305 rhoads
static int FlashBlock;
102 302 rhoads
 
103
//Free unused flash blocks
104
static int MediaBlockCleanup(void)
105
{
106 305 rhoads
   int i, sector, block, count=0;
107 302 rhoads
   unsigned char *buf;
108
 
109
   printf("FlashCleanup\n");
110 305 rhoads
   buf = (unsigned char*)malloc(FLASH_SECTOR_SIZE);
111 302 rhoads
   if(buf == NULL)
112
      return 0;
113 305 rhoads
   for(sector = FLASH_OFFSET / FLASH_SECTOR_SIZE; sector < FLASH_SIZE / FLASH_SECTOR_SIZE; ++sector)
114 302 rhoads
   {
115 305 rhoads
      FlashRead((uint16*)buf, FLASH_SECTOR_SIZE*sector, FLASH_SECTOR_SIZE);
116 307 rhoads
      if(sector == FLASH_OFFSET / FLASH_SECTOR_SIZE)
117 302 rhoads
      {
118
         for(i = 0; i < FLASH_BLOCKS/8; ++i)
119
            FlashBlockEmpty[i] |= ~FlashBlockUsed[i];
120
         memcpy(buf, FlashBlockEmpty, sizeof(FlashBlockEmpty));
121
         memset(FlashBlockUsed, 0xff, sizeof(FlashBlockUsed));
122
         memset(buf+sizeof(FlashBlockEmpty), 0xff, sizeof(FlashBlockUsed));
123
      }
124
      //Erase empty blocks
125 305 rhoads
      for(block = 0; block < FLASH_SECTOR_SIZE / FLASH_BLOCK_SIZE; ++block)
126 302 rhoads
      {
127 305 rhoads
         i = sector * FLASH_SECTOR_SIZE / FLASH_BLOCK_SIZE + block;
128 302 rhoads
         if(FlashBlockEmpty[i >> 3] & (1 << (i & 7)))
129
         {
130 305 rhoads
            memset(buf + FLASH_BLOCK_SIZE*block, 0xff, FLASH_BLOCK_SIZE);
131 302 rhoads
            ++count;
132
         }
133
      }
134 305 rhoads
      FlashErase(FLASH_SECTOR_SIZE * sector);
135
      FlashWrite((uint16*)buf, FLASH_SECTOR_SIZE * sector, FLASH_SECTOR_SIZE);
136 302 rhoads
   }
137
   free(buf);
138
   return count;
139
}
140
 
141
 
142
int MediaBlockInit(void)
143
{
144 305 rhoads
   FlashRead((uint16*)FlashBlockEmpty, FLASH_OFFSET, sizeof(FlashBlockEmpty));
145
   FlashRead((uint16*)FlashBlockUsed, FLASH_OFFSET+sizeof(FlashBlockEmpty),
146
             sizeof(FlashBlockUsed));
147
   FlashBlock = FLASH_START;
148
   return FlashBlockEmpty[FlashBlock >> 3] & (1 << (FlashBlock & 7));
149 302 rhoads
}
150
#endif
151
 
152
 
153 219 rhoads
static uint32 MediaBlockMalloc(OS_FILE *file)
154
{
155 302 rhoads
   int i, j;
156
   (void)i; (void)j;
157
 
158 219 rhoads
   if(file->fileEntry.mediaType == FILE_MEDIA_RAM)
159
      return (uint32)malloc(file->fileEntry.blockSize);
160 302 rhoads
#ifdef INCLUDE_FLASH
161
   //Find empty flash block
162 305 rhoads
   for(i = FlashBlock; i < FLASH_BLOCKS; ++i)
163 302 rhoads
   {
164
      if(FlashBlockEmpty[i >> 3] & (1 << (i & 7)))
165
      {
166 305 rhoads
         FlashBlock = i + 1;
167 302 rhoads
         FlashBlockEmpty[i >> 3] &= ~(1 << (i & 7));
168
         j = i >> 3;
169
         j &= ~1;
170 305 rhoads
         FlashWrite((uint16*)(FlashBlockEmpty + j), FLASH_OFFSET + j, 2);
171 302 rhoads
         return i;
172
      }
173
   }
174
 
175
   i = MediaBlockCleanup();
176
   if(i == 0)
177
      return 0;
178 305 rhoads
   FlashBlock = FLASH_START;
179 302 rhoads
   return MediaBlockMalloc(file);
180
#else
181
   return 0;
182
#endif
183 219 rhoads
}
184
 
185
 
186
static void MediaBlockFree(OS_FILE *file, uint32 blockIndex)
187
{
188
   if(file->fileEntry.mediaType == FILE_MEDIA_RAM)
189
      free((void*)blockIndex);
190 302 rhoads
#ifdef INCLUDE_FLASH
191 219 rhoads
   else
192 302 rhoads
   {
193
      int i=blockIndex, j;
194
      FlashBlockUsed[i >> 3] &= ~(1 << (i & 7));
195
      j = i >> 3;
196
      j &= ~1;
197 305 rhoads
      FlashWrite((uint16*)(FlashBlockUsed + j), FLASH_OFFSET + sizeof(FlashBlockEmpty) + j, 2);
198 302 rhoads
   }
199
#endif
200 219 rhoads
}
201
 
202
 
203
static void MediaBlockRead(OS_FILE *file, uint32 blockIndex)
204
{
205
   if(file->fileEntry.mediaType == FILE_MEDIA_RAM)
206
      file->block = (OS_Block_t*)blockIndex;
207 302 rhoads
#ifdef INCLUDE_FLASH
208 219 rhoads
   else
209
   {
210
      if(file->blockLocal == NULL)
211 305 rhoads
         file->blockLocal = (OS_Block_t*)malloc(FLASH_BLOCK_SIZE);
212 219 rhoads
      file->block = file->blockLocal;
213 305 rhoads
      FlashRead((uint16*)file->block, blockIndex << FLASH_LN2_SIZE, FLASH_BLOCK_SIZE);
214 219 rhoads
   }
215 302 rhoads
#endif
216 219 rhoads
}
217
 
218
 
219 302 rhoads
static void MediaBlockWrite(OS_FILE *file, uint32 blockIndex)
220 219 rhoads
{
221 302 rhoads
   (void)file;
222
   (void)blockIndex;
223
#ifdef INCLUDE_FLASH
224 219 rhoads
   if(file->fileEntry.mediaType != FILE_MEDIA_RAM)
225 305 rhoads
      FlashWrite((uint16*)file->block, blockIndex << FLASH_LN2_SIZE, FLASH_BLOCK_SIZE);
226 302 rhoads
#endif
227 219 rhoads
}
228
 
229
/***************** Media Functions End *************************/
230
 
231
// Get the next block and write the old block if it was modified
232
static void BlockRead(OS_FILE *file, uint32 blockIndex)
233
{
234
   uint32 blockIndexSave = blockIndex;
235 302 rhoads
 
236
   OS_MutexPend(mutexFilesys);
237 219 rhoads
   if(blockIndex == BLOCK_MALLOC)
238
   {
239
      // Get a new block
240
      blockIndex = MediaBlockMalloc(file);
241
      if(blockIndex == 0)
242
         blockIndex = BLOCK_EOF;
243
      if(file->block)
244
      {
245
         // Set next pointer in previous block
246
         file->block->next = blockIndex;
247
         file->blockModified = 1;
248
      }
249
   }
250
   if(file->block && file->blockModified)
251
   {
252
      // Write block back to flash or disk
253 302 rhoads
      MediaBlockWrite(file, file->blockIndex);
254 219 rhoads
      file->blockModified = 0;
255
   }
256
   if(blockIndex == BLOCK_EOF)
257 302 rhoads
   {
258
      OS_MutexPost(mutexFilesys);
259 219 rhoads
      return;
260 302 rhoads
   }
261 219 rhoads
   file->blockIndex = blockIndex;
262
   file->blockOffset = 0;
263
   MediaBlockRead(file, blockIndex);
264
   if(blockIndexSave == BLOCK_MALLOC)
265
   {
266
      memset(file->block, 0xff, file->fileEntry.blockSize);
267
      file->blockModified = 1;
268
   }
269 302 rhoads
   OS_MutexPost(mutexFilesys);
270 219 rhoads
}
271
 
272
 
273
int OS_fread(void *buffer, int size, int count, OS_FILE *file)
274
{
275
   int items, bytes;
276
   uint8 *buf = (uint8*)buffer;
277
 
278
   for(items = 0; items < count; ++items)
279
   {
280
      for(bytes = 0; bytes < size; ++bytes)
281
      {
282
         if(file->fileOffset >= file->fileEntry.length &&
283
            file->fileEntry.isDirectory == 0)
284
            return items;
285
         if(file->blockOffset >= file->fileEntry.blockSize - sizeof(uint32))
286
         {
287
            if(file->block->next == BLOCK_EOF)
288
               return items;
289
            BlockRead(file, file->block->next);
290
         }
291
         *buf++ = file->block->data[file->blockOffset++];
292
         ++file->fileOffset;
293
      }
294
   }
295
   return items;
296
}
297
 
298
 
299
int OS_fwrite(void *buffer, int size, int count, OS_FILE *file)
300
{
301
   int items, bytes;
302
   uint8 *buf = (uint8*)buffer;
303
 
304 302 rhoads
   OS_MutexPend(mutexFilesys);
305 219 rhoads
   file->blockModified = 1;
306
   for(items = 0; items < count; ++items)
307
   {
308
      for(bytes = 0; bytes < size; ++bytes)
309
      {
310
         if(file->blockOffset >= file->fileEntry.blockSize - sizeof(uint32))
311
         {
312
            if(file->block->next == BLOCK_EOF)
313
               file->block->next = BLOCK_MALLOC;
314
            BlockRead(file, file->block->next);
315
            if(file->blockIndex == BLOCK_EOF)
316
            {
317
               count = 0;
318
               --items;
319
               break;
320
            }
321
            file->blockModified = 1;
322
         }
323
         file->block->data[file->blockOffset++] = *buf++;
324
         ++file->fileOffset;
325
      }
326
   }
327
   file->blockModified = 1;
328
   file->fileModified = 1;
329
   if(file->fileOffset > file->fileEntry.length)
330
      file->fileEntry.length = file->fileOffset;
331 302 rhoads
   OS_MutexPost(mutexFilesys);
332 219 rhoads
   return items;
333
}
334
 
335
 
336
int OS_fseek(OS_FILE *file, int offset, int mode)
337
{
338
   if(mode == 1)      //SEEK_CUR
339
      offset += file->fileOffset;
340
   else if(mode == 2) //SEEK_END
341
      offset += file->fileEntry.length;
342
   file->fileOffset = offset;
343
   BlockRead(file, file->fileEntry.blockIndex);
344
   while(offset > (int)file->fileEntry.blockSize - (int)sizeof(uint32))
345
   {
346
      BlockRead(file, file->block->next);
347
      offset -= file->fileEntry.blockSize - (int)sizeof(uint32);
348
   }
349
   file->blockOffset = offset;
350
   return 0;
351
}
352
 
353
 
354
static int FileOpen(OS_FILE *file, char *name, OS_FileEntry_t *fileEntry)
355
{
356
   memset(file, 0, sizeof(OS_FILE));
357
   if(fileEntry == NULL)
358
   {
359
      // Open root file
360
      memcpy(&file->fileEntry, &rootFileEntry, sizeof(OS_FileEntry_t));
361
   }
362
   else if(fileEntry->valid == 1)
363
   {
364
      // Open existing file
365
      memcpy(&file->fileEntry, fileEntry, sizeof(OS_FileEntry_t));
366
   }
367
   else
368
   {
369
      // Initialize new file
370
      file->fileModified = 1;
371
      file->blockModified = 1;
372
      memset(&file->fileEntry, 0, sizeof(OS_FileEntry_t));
373
      file->fileEntry.isDirectory = 0;
374
      file->fileEntry.length = 0;
375
      strncpy(file->fileEntry.name, name, FILE_NAME_SIZE-1);
376
      file->fileEntry.blockIndex = 0;
377
      file->fileEntry.valid = 1;
378
      file->fileEntry.blockSize = fileEntry->blockSize;
379
      file->fileEntry.mediaType = fileEntry->mediaType;
380
   }
381
   BlockRead(file, file->fileEntry.blockIndex);    //Get first block
382
   file->fileEntry.blockIndex = file->blockIndex;
383
   file->fileOffset = 0;
384
   if(file->blockIndex == BLOCK_EOF)
385
      return -1;
386
   return 0;
387
}
388
 
389
 
390
static int FileFind(OS_FILE *directory, char *name, OS_FileEntry_t *fileEntry)
391
{
392
   int count, rc = -1;
393
   uint32 blockIndex, blockOffset;
394
   uint32 blockIndexEmpty=BLOCK_EOF, blockOffsetEmpty=0;
395
 
396
   // Loop through files in directory
397
   for(;;)
398
   {
399
      blockIndex = directory->blockIndex;
400
      blockOffset = directory->blockOffset;
401
      count = OS_fread(fileEntry, sizeof(OS_FileEntry_t), 1, directory);
402
      if(count == 0 || fileEntry->blockIndex == BLOCK_EOF)
403
         break;
404
      if(fileEntry->valid == 1 && strcmp(fileEntry->name, name) == 0)
405
      {
406
         rc = 0;  //Found the file in the directory
407
         break;
408
      }
409
      if(fileEntry->valid != 1 && blockIndexEmpty == BLOCK_EOF)
410
      {
411
         blockIndexEmpty = blockIndex;
412
         blockOffsetEmpty = blockOffset;
413
      }
414
   }
415
   if(rc == 0 || directory->fileEntry.mediaType == FILE_MEDIA_FLASH ||
416
      blockIndexEmpty == BLOCK_EOF)
417
   {
418
      // Backup to start of fileEntry or last entry in directory
419
      if(directory->blockIndex != blockIndex)
420
         BlockRead(directory, blockIndex);
421
      directory->blockOffset = blockOffset;
422
   }
423
   else
424
   {
425
      // Backup to empty slot
426
      if(directory->blockIndex != blockIndexEmpty)
427
         BlockRead(directory, blockIndexEmpty);
428
      directory->blockOffset = blockOffsetEmpty;
429
   }
430
   return rc;
431
}
432
 
433
 
434
static int FileFindRecursive(OS_FILE *directory, char *name,
435
                             OS_FileEntry_t *fileEntry, char *filename)
436
{
437
   int rc, length;
438
 
439
   rc = FileOpen(directory, NULL, NULL);            //Open root directory
440
   for(;;)
441
   {
442
      if(name[0] == '/')
443
         ++name;
444
      for(length = 0; length < FILE_NAME_SIZE; ++length)
445
      {
446
         if(name[length] == 0 || name[length] == '/')
447
            break;
448
         filename[length] = name[length];
449
      }
450
      filename[length] = 0;
451
      rc = FileFind(directory, filename, fileEntry);  //Find file
452
      if(rc)
453
      {
454
         // File not found
455
         fileEntry->mediaType = directory->fileEntry.mediaType;
456
         fileEntry->blockSize = directory->fileEntry.blockSize;
457
         if(strstr(name, "/") == NULL)
458
            return rc;
459
         else
460
            return -2;  //can't find parent directory
461
      }
462
      name += length;
463
      if(name[0])
464
         rc = FileOpen(directory, filename, fileEntry);  //Open subdir
465
      else
466
         break;
467
   }
468
   return rc;
469
}
470
 
471
 
472
OS_FILE *OS_fopen(char *name, char *mode)
473
{
474
   OS_FILE *file;
475
   OS_FileEntry_t fileEntry;
476
   OS_FILE dir;
477
   char filename[FILE_NAME_SIZE];  //Name without directories
478
   int rc;
479
 
480
   if(rootFileEntry.blockIndex == 0)
481
   {
482
      // Mount file system
483 302 rhoads
      mutexFilesys = OS_MutexCreate("filesys");
484 219 rhoads
      memset(&dir, 0, sizeof(OS_FILE));
485
      dir.fileEntry.blockSize = BLOCK_SIZE;
486
      //dir.fileEntry.mediaType = FILE_MEDIA_FLASH;  //Test flash
487
      BlockRead(&dir, BLOCK_MALLOC);
488
      strcpy(rootFileEntry.name, "/");
489
      rootFileEntry.mediaType = dir.fileEntry.mediaType;
490
      rootFileEntry.blockIndex = dir.blockIndex;
491
      rootFileEntry.blockSize = dir.fileEntry.blockSize;
492
      rootFileEntry.isDirectory = 1;
493
      BlockRead(&dir, BLOCK_EOF);    //Flush data
494 302 rhoads
#ifdef INCLUDE_FLASH
495
      file = OS_fopen("flash", "w+");
496
      if(file == NULL)
497
         return NULL;
498
      file->fileEntry.isDirectory = 1;
499
      file->fileEntry.mediaType = FILE_MEDIA_FLASH;
500 305 rhoads
      file->fileEntry.blockSize = FLASH_BLOCK_SIZE;
501 302 rhoads
      file->blockLocal = file->block;
502
      file->block = NULL;
503
      rc = MediaBlockInit();
504
      if(rc == 1)
505
         BlockRead(file, BLOCK_MALLOC);
506
      else
507 305 rhoads
         BlockRead(file, FLASH_START);
508 302 rhoads
      file->fileEntry.blockIndex = file->blockIndex;
509
      OS_fclose(file);
510
#endif
511 219 rhoads
   }
512
 
513
   file = (OS_FILE*)malloc(sizeof(OS_FILE));
514
   if(file == NULL)
515
      return NULL;
516 302 rhoads
   OS_MutexPend(mutexFilesys);
517 228 rhoads
   if(name[0] == 0 || strcmp(name, "/") == 0)
518 219 rhoads
   {
519
      FileOpen(file, NULL, NULL);
520 302 rhoads
      OS_MutexPost(mutexFilesys);
521 219 rhoads
      return file;
522
   }
523
   if(strcmp(mode, "w") == 0)
524
      OS_fdelete(name);
525
   rc = FileFindRecursive(&dir, name, &fileEntry, filename);
526
   if(dir.blockLocal)
527
      free(dir.blockLocal);
528
   if(rc == -2 || (rc && mode[0] == 'r'))
529
   {
530
      free(file);
531 302 rhoads
      OS_MutexPost(mutexFilesys);
532 219 rhoads
      return NULL;
533
   }
534
   rc = FileOpen(file, filename, &fileEntry);  //Open file
535
   file->fullname[0] = 0;
536
   strncat(file->fullname, name, FULL_NAME_SIZE);
537 302 rhoads
   OS_MutexPost(mutexFilesys);
538 219 rhoads
   return file;
539
}
540
 
541
 
542
void OS_fclose(OS_FILE *file)
543
{
544
   OS_FileEntry_t fileEntry;
545
   OS_FILE dir;
546
   char filename[FILE_NAME_SIZE];
547
   int rc;
548
 
549
   if(file->fileModified)
550
   {
551
      // Write file->fileEntry into parent directory
552 302 rhoads
      OS_MutexPend(mutexFilesys);
553 219 rhoads
      BlockRead(file, BLOCK_EOF);
554
      rc = FileFindRecursive(&dir, file->fullname, &fileEntry, filename);
555
      if(file->fileEntry.mediaType == FILE_MEDIA_FLASH && rc == 0)
556
      {
557
         // Invalidate old entry and add new entry at the end
558
         fileEntry.valid = 0;
559
         OS_fwrite(&fileEntry, sizeof(OS_FileEntry_t), 1, &dir);
560
         FileFind(&dir, "endoffile", &fileEntry);
561
      }
562
      OS_fwrite(&file->fileEntry, sizeof(OS_FileEntry_t), 1, &dir);
563
      BlockRead(&dir, BLOCK_EOF);  //flush data
564
      if(dir.blockLocal)
565
         free(dir.blockLocal);
566 302 rhoads
      OS_MutexPost(mutexFilesys);
567 219 rhoads
   }
568
   if(file->blockLocal)
569
      free(file->blockLocal);
570
   free(file);
571
}
572
 
573
 
574
int OS_fmkdir(char *name)
575
{
576
   OS_FILE *file;
577
   file = OS_fopen(name, "w+");
578
   if(file == NULL)
579
      return -1;
580
   file->fileEntry.isDirectory = 1;
581
   OS_fclose(file);
582
   return 0;
583
}
584
 
585
 
586
void OS_fdelete(char *name)
587
{
588
   OS_FILE dir, file;
589
   OS_FileEntry_t fileEntry;
590
   int rc;
591
   uint32 blockIndex;
592
   char filename[FILE_NAME_SIZE];  //Name without directories
593
 
594 302 rhoads
   OS_MutexPend(mutexFilesys);
595 219 rhoads
   rc = FileFindRecursive(&dir, name, &fileEntry, filename);
596
   if(rc == 0)
597
   {
598
      FileOpen(&file, NULL, &fileEntry);
599
      for(blockIndex = file.blockIndex; file.block->next != BLOCK_EOF; blockIndex = file.blockIndex)
600
      {
601
         BlockRead(&file, file.block->next);
602
         MediaBlockFree(&file, blockIndex);
603
      }
604
      MediaBlockFree(&file, blockIndex);
605
      fileEntry.valid = 0;
606
      OS_fwrite((char*)&fileEntry, sizeof(OS_FileEntry_t), 1, &dir);
607
      BlockRead(&dir, BLOCK_EOF);
608
      if(file.blockLocal)
609
         free(file.blockLocal);
610
   }
611
   if(dir.blockLocal)
612
      free(dir.blockLocal);
613 302 rhoads
   OS_MutexPost(mutexFilesys);
614 219 rhoads
}
615
 
616
 
617
int OS_fdir(OS_FILE *dir, char name[64])
618
{
619
   OS_FileEntry_t *fileEntry = (OS_FileEntry_t*)name;
620
   int count;
621
   for(;;)
622
   {
623
      count = OS_fread(fileEntry, sizeof(OS_FileEntry_t), 1, dir);
624
      if(count == 0 || fileEntry->blockIndex == BLOCK_EOF)
625
         return -1;
626
      if(fileEntry->valid == 1)
627
         break;
628
   }
629
   return 0;
630
}
631
 
632
/*************************************************/
633
#define TEST_FILES
634
#ifdef TEST_FILES
635
int DirRecursive(char *name)
636
{
637
   OS_FileEntry_t fileEntry;
638
   OS_FILE *dir;
639
   char fullname[FULL_NAME_SIZE];
640
   int rc;
641
 
642
   dir = OS_fopen(name, "r");
643
   for(;;)
644
   {
645
      rc = OS_fdir(dir, (char*)&fileEntry);
646
      if(rc)
647
         break;
648
      printf("%s %d\n", fileEntry.name, fileEntry.length);
649
      if(fileEntry.isDirectory)
650
      {
651
         if(strcmp(name, "/") == 0)
652
            sprintf(fullname, "/%s", fileEntry.name);
653
         else
654
            sprintf(fullname, "%s/%s", name, fileEntry.name);
655
         DirRecursive(fullname);
656
      }
657
   }
658
   OS_fclose(dir);
659
   return 0;
660
}
661
 
662
int OS_ftest(void)
663
{
664
   OS_FILE *file;
665
   char *buf;
666
   int count;
667
   int i, j;
668
 
669
   buf = (char*)malloc(5000);
670
   memset(buf, 0, 5000);
671
   for(count = 0; count < 4000; ++count)
672
      buf[count] = (char)('A' + (count % 26));
673
   OS_fmkdir("dir");
674
   OS_fmkdir("/dir/subdir");
675
   file = OS_fopen("/dir/subdir/test.txt", "w");
676
   count = OS_fwrite(buf, 1, 4000, file);
677
   OS_fclose(file);
678
   memset(buf, 0, 5000);
679
   file = OS_fopen("/dir/subdir/test.txt", "r");
680
   count = OS_fread(buf, 1, 5000, file);
681
   OS_fclose(file);
682
   printf("(%s)\n", buf);
683
 
684
   DirRecursive("/");
685
 
686
   for(i = 0; i < 5; ++i)
687
   {
688
      sprintf(buf, "/dir%d", i);
689
      OS_fmkdir(buf);
690
      for(j = 0; j < 5; ++j)
691
      {
692
         sprintf(buf, "/dir%d/file%d%d", i, i, j);
693
         file = OS_fopen(buf, "w");
694
         sprintf(buf, "i=%d j=%d", i, j);
695
         OS_fwrite(buf, 1, 8, file);
696
         OS_fclose(file);
697
      }
698
   }
699
 
700
   OS_fdelete("/dir1/file12");
701
   DirRecursive("/");
702
   file = OS_fopen("/baddir/myfile.txt", "w");
703
   if(file)
704
      printf("ERROR!\n");
705
 
706
   for(i = 0; i < 5; ++i)
707
   {
708
      for(j = 0; j < 5; ++j)
709
      {
710
         sprintf(buf, "/dir%d/file%d%d", i, i, j);
711
         file = OS_fopen(buf, "r");
712
         if(file)
713
         {
714
            count = OS_fread(buf, 1, 500, file);
715
            printf("i=%d j=%d count=%d (%s)\n", i, j, count, buf);
716
            OS_fclose(file);
717
         }
718
      }
719
   }
720
 
721
   OS_fdelete("/dir/subdir/test.txt");
722
   OS_fdelete("/dir/subdir");
723
   OS_fdelete("/dir");
724
   for(i = 0; i < 5; ++i)
725
   {
726
      for(j = 0; j < 5; ++j)
727
      {
728
         sprintf(buf, "/dir%d/file%d%d", i, i, j);
729
         OS_fdelete(buf);
730
      }
731
      sprintf(buf, "/dir%d", i);
732
      OS_fdelete(buf);
733
   }
734
 
735
   DirRecursive("/");
736
 
737
   free(buf);
738
   return 0;
739
}
740
#endif  //TEST_FILES

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.