· 6 years ago · Jun 10, 2019, 07:32 PM
1/*********************************************************************************/
2/* FILE */
3/*********************************************************************************/
4#ifndef __INCLUDED_DIRDB_H__
5#define __INCLUDED_DIRDB_H__
6
7//
8#define DIRDB_GUARD 0xFCE2E38B
9
10//
11#define RV_DIRFULL -1984
12
13// Types
14#define ID_DIRECTORY 0x10
15#define ID_FILE 0x20
16
17//
18#include "kernel32.h"
19
20//====================================================================================
21// >> Preferences for directory database system
22#define MAX_CACHED_FILE_SIZE (1024*1024*2) // 2 megabytes at most
23#define MAX_DIRS_CACHED 400
24#define MAX_ENTRIES_PER_DIR 200
25#define MAX_BYTES_PER_DIR (sizeof(JTMFS_FILE_ENTRY)*MAX_ENTRIES_PER_DIR)
26
27//====================================================================================
28//
29// DIRECTORY CACHE ENTRY STRUCTURE DEFINITION.
30//
31typedef struct
32{
33 // Guard variable
34 DWORD guard;
35
36 // Set to non-zero value if this entry is allocated,
37 // zero will indicate that the entry is free.
38 char isfree;
39
40 // Some data changed since last flush.
41 // This variable is mostly useful for the dirdb
42 // cache flush process.
43 char flushRequired;
44
45 // Running number that is used for checking
46 // that the directory is the same as we were
47 // accessing before.
48 // E.g. cache changes might happend in middle.
49 int run;
50
51 // Type of item
52 int type;
53
54 // Number of entries currently exists on this dir
55 int n_entries;
56 // Buffer where to store the directory
57 BYTE *buf;
58 int l_buf;
59
60 // -1 = UNKNOWN
61 // Other values point to the entry # of an empty entry
62 int empty_entry;
63 int blocks;
64
65 // Directory Block #, Device #
66 int db,dnr;
67
68 // Block offset
69 struct
70 {
71 int s,e;
72 }offs;
73}DIR;
74
75//
76//#define FILE DIR
77
78// DIRECTORY DATABASE MAIN STRUCTURE
79typedef struct
80{
81 // 0 = DB is free for access
82 // 1 = DB is reserved
83 // 2 = DB is free for database flush operation
84 // and is reserved for all other operations,
85 // after flush has been done state is set to l_state.
86 int state;
87 // Temporary variable
88 int l_state;
89
90 // Structures for cached directories
91 DIR dir[(MAX_DIRS_CACHED+10)];
92 // Number of directories currently registered in database
93 int n_entries;
94 // Number of total directories in database
95 int total;
96
97 // Set to non-zero when cache flush is recommended
98 int cacheFlushRec;
99}DIRDB;
100
101//
102extern DIRDB dirdb;
103
104//
105void pause(const char *s);
106
107//
108#include "dirdbCorruption.h"
109
110#endif
111
112
113
114/*********************************************************************************/
115/* FILE */
116/*********************************************************************************/
117
118//
119#ifndef __INCLUDED_DIRTYPE_H__
120#define __INCLUDED_DIRTYPE_H__
121
122//
123#define JTMFS_ID_WRITEONLY 0x01
124#define JTMFS_ID_SYSTEM 0x02
125#define JTMFS_ID_DEVICE 0x04
126#define JTMFS_ID_ARCHIVE 0x08
127#define JTMFS_ID_EXECUTABLE 0x10
128#define JTMFS_ID_HIDDEN 0x20
129#define JTMFS_ID_DIRNAME 0x40
130#define JTMFS_ID_DIRECTORY 0x80
131
132#endif
133
134//
135
136
137
138/*********************************************************************************/
139/* FILE */
140/*********************************************************************************/
141//
142#ifndef __INCLUDED_FLEXCORRUPTION_H__
143#define __INCLUDED_FLEXCORRUPTION_H__
144
145//
146void jtmfatInformation(void);
147void jtmfatInformation1(FLEFAT *e, const char *name);
148int checkFat(FLEFAT *e);
149int ffCheck(const char *fn, const char *func, int line);
150
151//
152#define FFCHECK ffCheck(__FILE__, __FUNCTION__, __LINE__);
153
154//
155#define FLEXCHECK(x) if(1){ \
156 if(checkFat( ((FLEFAT*)x) )==FALSE)\
157 { \
158 SetThreadTerminal(GetCurrentThread(), 0);\
159 Attention();\
160 printk("Corruption detected: function %s, file %s, line %d\n",\
161 __FUNCTION__, __FILE__, __LINE__);\
162 panic("Corruption detected!"); \
163 } } \
164
165//
166#define jtmfatChecker(); FFCHECK
167
168#endif
169
170
171
172
173
174
175/*********************************************************************************/
176/* FILE */
177/*********************************************************************************/
178#ifndef __INCLUDED_FLEXFAT_H__
179#define __INCLUDED_FLEXFAT_H__
180
181// (in bytes)
182#define MAX_FAT_SIZE (1024*1024*64)
183//
184#define INITIALIZED 0x136FD2DA
185
186//
187#define N_MAX_FATS 100
188
189// FlexFat's errors will be always displayed due to it's importancity.
190#define FLEXER(ERRNO, EXPLANATION) printk("Flex error(%s) #%d\n", __FUNCTION__, ERRNO); \
191printk(EXPLANATION); \
192//panic(EXPLANATION);
193
194//
195#define FLFGUARD 0xFCE2E37B
196
197//
198#define READ 0
199#define WRITE 1
200
201//
202// ------------------------------------------------------------------
203// Flex FAT
204typedef struct
205{
206 // Is OK(ready)? (TRUE OR FALSE)
207 int isOK;
208
209 // Buffer properties
210 // -----------------
211 // Guard DWORD (0xFCE2E37B)
212 DWORD guard;
213 // PTR to data buffer(DWORD PTR for 32-bit FAT)
214 DWORD *buf;
215 // Amount of entries (DWORD) on this FAT
216 int amount;
217 // Lenght of the buffer
218 int l_buf;
219 // Map of which blocks to write back on disk
220 BYTE *writemap;
221 // --
222 int l_writemap;
223 // DNR/BNR of the currently cached region of the FAT
224 int dnr, bnr;
225 // This buffer contains currently something that
226 // has to be written back on disk?
227 int writeBack;
228
229 // Drive properties
230 // ----------------
231 // Block size for this DNR
232 int bs;
233
234 //
235 DWORD status;
236
237 //
238 DWORD max_val;
239
240 // Boot block(contains block number # to the FAT table)
241 JTMFAT_INFOBLOCK *bb;
242}FLEFAT;
243
244//
245typedef struct
246{
247 // FAT structures for hundred devices
248 FLEFAT FAT[N_MAX_FATS];
249}FLEFATSYS;
250
251// Function prototypes
252void flexFlushFAT(int dnr);
253void flexDiskChange(int dnr);
254void clearFatContents(FLEFAT *f);
255void jtmfatInformation1(FLEFAT *e, const char *name);
256void jtmfatInformation(void);
257int _flexFatGetBlock(const char *caller, int dnr,int X);
258int _flexFatSetBlock(const char *caller, int dnr,int X,int VALUE);
259int FastSetBlocks(int dnr, int x1, int x2, int what);
260void AnalyzeFAT(FLEFAT *f);
261
262//
263#define FastGetBlock(dnr,which) _FastGetBlock(__FUNCTION__, dnr,which)
264#define FastSetBlock(dnr,which,what) _FastSetBlock(__FUNCTION__, dnr,which,what)
265//int _FastGetBlock(char *fun, int dnr, int which);
266//int _FastSetBlock(char *fun, int dnr, int which, DWORD what);
267void flexHealthCheck(void);
268void flexRWFAT(FLEFAT *f, int rw);
269
270//
271extern char flextmp[256];
272extern int flexActive;
273
274// Flex FAT main structure
275extern FLEFATSYS *fle;
276
277//
278#include "flexCorruption.h"
279
280//
281void AnalyzeFATs(void);
282
283#endif
284
285
286
287/*********************************************************************************/
288/* FILE */
289/*********************************************************************************/
290#ifndef __INCLUDED_FNAME_TRANSLATION__
291#define __INCLUDED_FNAME_TRANSLATION__
292
293int tell_fname(const char *fname, char *parsedfname);
294
295#endif
296
297/*********************************************************************************/
298/* FILE */
299/*********************************************************************************/
300//
301#ifndef __INCLUDED_FORMAT_H__
302#define __INCLUDED_FORMAT_H__
303
304//
305int jtmfs_formatdrive(int device_nr);
306
307#endif
308
309
310
311
312
313/*********************************************************************************/
314/* FILE */
315/*********************************************************************************/
316
317#ifndef __INCLUDED_JTMFAT_H__
318#define __INCLUDED_JTMFAT_H__
319
320// On which block does the info block reside?
321// (Block) (Description)
322// 0: Boot code/data
323// 1: Partition table
324// 2: JTMFS information block
325#define FAT_INFO_BLOCK_OFFS 512
326#define FAT_BOOT_SECTION_LEN_K 16
327#define KERNEL_LEN_K 512
328
329// Enable new FLEXFAT system.
330#define FLEXFAT
331
332//
333#define jtmfat_getrootdir(x) _jtmfat_getrootdir(__FUNCTION__, x)
334
335// Remove remarks from the defination below
336// if you want to enable strict perfection -option.
337// This option will cause panics on some concurrent
338// problems, rather than trying to fix these.
339//// #define STRICT_PERFECTION
340
341// When formatting a drive, this is a max. value of how many
342// times the progress indicator status must be updated.
343// 100 means 100 times, this means update on every % increase.
344// (obsolete)
345#define INDICATOR_RADIUS 100
346
347// Safe guard line that is REQUIRED!
348// Recommanded: 1024*8 (8K)
349#define FAT_SAFEGUARD 1024*512
350// Contains roadmap for the FAT table.
351#define L_ROADMAP getsize(dnr)
352// Contains cache 32-bit FAT table(4 bytes per entry):
353#define L_FATCACHE getsize(dnr)*4
354// Contains CFAT structures for max. X different devices(X=value below).
355#define N_CFAT_STRUCTURES 100
356
357//
358//#define JTMFAT_ALLOWTEXTS
359// Uncomment this out if you want warnings/etc messages to be shown too.
360//#define __DJTMFAT__
361
362//
363#include "basdef.h"
364#include "devapi.h"
365
366//
367typedef struct
368{
369 // 11 bytes: (512-11 = 501)
370
371 // Kernel 16-bit checksum.
372 WORD correct_kernel_checksum;
373 // Boot section length(offset to kernel on drive).
374 WORD boot_len_k;
375 // CHS settings.
376 WORD cylinders;
377 BYTE heads;
378 BYTE sectors;
379 // BIOS boot drive.
380 BYTE bootdrv;
381 // Boot record signature.
382 // (0x55AA)
383 WORD signature;
384}BOOTRECORD;
385
386// 48 bytes bootblock,
387// res1,res2 = will contain sufficient space for the ASM jump instruction
388// which will jump past the description information, to the code
389// beginning after res7.
390//
391// New rule:
392// Offsets now mean block numbers,
393// aka block offset.
394// length = length in blocks
395//
396typedef struct
397{
398 // First eight bytes are reserved(res1,res2 DWORDs).
399 DWORD res1,res2;
400 // Boot drive (0=floppy A:, 1=floppy B:, 0x80=drive C:, 0x81=drive D:).
401 BYTE bootdrv;
402 // Detection string: "JTMFS",0
403 char detstr[6];
404 // Offset to FAT and data area.
405 DWORD fat_offs;
406 DWORD data_offs;
407 DWORD kernel_offs; // 0 if no kernel featured.
408 // System area length in 512 bytes blocks.
409 DWORD sysarea_length; // (blocks)
410 // System area before the data area,
411 // system area is:
412 // A) boot block B) info block C) FAT (in bytes)
413 DWORD fat_length; // (blocks)
414 // sysarea_length.
415 DWORD bootblock_size; // (blocks)
416 // DEVICE SPECIFIC.
417 DWORD n_blocks,block_size;
418 // FAT table checksum.
419 DWORD fatChecksum32;
420 // Max. value allowed on FAT table.
421 int max_val;
422 // Reserved.
423 DWORD res3,res4,res5,res6,res7;
424}JTMFAT_INFOBLOCK;
425
426//
427typedef struct
428{
429 char isActive;
430
431 //
432 DWORD *buf;
433 int l_buf;
434
435 //
436 BYTE *actual;
437 int l_actual;
438
439 //
440 char *roadMap; // Info about which block has changed
441 int l_roadMap;
442
443 //
444 int requiresFlush;
445}CFAT;
446
447//
448typedef struct
449{
450 // Is drive removable?
451 char isRemovable;
452 // Last time when boot block was reloaded.
453 int t;
454}BOOTINF;
455
456//
457typedef struct
458{
459 // This is a new device? We have to load information of it,
460 // where fat is located, how big it is, how big the device is, etc..
461 // (This variable is set to non-zero usually by jtmfat_chdev)
462 int virgin;
463 // device number
464 int dnr;
465 // the bootblock, which contains all information
466 // jtmfat_chdev will reload new bootblock to this structure.
467 JTMFAT_INFOBLOCK *bb[100]; // << 100 is max. devices now !!!! (2)
468 // This device have been formatted to JTMFS? 0=Nope, 1=Yes
469 int isJTMFS[100]; // << 100 is max. devices now !!!! (1)
470 // Boot block information.
471 BOOTINF bootinf[100];
472 // Temporary buffer, used for various purposes,
473 // f.e. for storing a piece of fat table.
474 BYTE *tmpbuf,*tbuf;
475
476 // FAT structures.
477 CFAT **fat;
478
479 //
480 BYTE *all_cfat_structures;
481 //
482}JTMFATSYS;
483
484//
485int _jtmfat_chdev(const char *caller, long dnr);
486//
487#define jtmfat_chdev(x) _jtmfat_chdev(__FUNCTION__, x)
488
489//
490int jtmfat_getrootdir1(int dnr);
491int _jtmfat_getrootdir(const char *caller, int dnr);
492int _jtmfat_loadinfoblock(const char *caller, int dnr);
493//
494#define jtmfat_loadinfoblock(x) \
495 _jtmfat_loadinfoblock(__FUNCTION__, x)
496
497//
498#define jtmfat_getblock(dnr, db) \
499 _flexFatGetBlock(__FUNCTION__, dnr, db)
500#define jtmfat_setblock(dnr, which, what) \
501 _flexFatSetBlock(__FUNCTION__, dnr,which,what)
502
503//
504long jtmfat_isJTMFS(int dnr);
505void jtmfat_flushfatcache(void);
506long jtmfat_getblocksallocated(long dnr);
507long jtmfat_getblocksfree(long dnr);
508long jtmfat_getfreeblock(long dnr);
509int write_fat(int dnr);
510int read_fat(int dnr);
511int jtmfat_deactivateFatDNR(int dnr);
512
513#define USE_DEBUGTRAP char __str[255];
514/*#define DEBUGTRAP strcpy(__str, __FUNCTION__); \
515DebugTrap(dnr, __str);*/
516
517#define DEBUGTRAP DebugTrap(dnr, __FUNCTION__);
518
519//
520JTMFAT_INFOBLOCK *jtmfat_getinfoblock(int dnr);
521void jtmfat_DiskChange(int dnr);
522
523//
524extern int jtmfat_ready;
525extern JTMFATSYS *fatsys;
526
527//
528#endif
529
530
531
532/*********************************************************************************/
533/* FILE */
534/*********************************************************************************/
535#ifndef __INCLUDED_JTMFS_H__
536#define __INCLUDED_JTMFS_H__
537
538//
539#include "basdef.h"
540#include "jtmfat.h"
541#include "devapi.h"
542#include "api.h"
543#include "jtmfsPath.h"
544#include "flexFat.h"
545#include "dirtype.h"
546
547//
548#define DEBUGLINE dprintk("[%s / %s Line %d]\n", \
549 __FILE__, __FUNCTION__, __LINE__);
550
551//
552#define JTMFSDEBUG
553//#define __JTMFS_DEBUG__
554
555//
556#define ENTRYLMT (0x200)
557
558//
559typedef struct
560{
561 char line[256];
562 char function[256];
563 char file[256];
564}DEBUGSTR;
565extern DEBUGSTR debugstr;
566
567#define DEBUGINFO dprintk("Function=%s, Line=%s, File=%s\n", \
568 debugstr.function, \
569 debugstr.line, \
570 debugstr.file);
571
572
573//
574#define DEBUGFUNC sprintf(debugstr.line, "%d", __LINE__); \
575 strcpy(debugstr.function, __FUNCTION__); \
576 strcpy(debugstr.file, __FILE__);
577
578//
579/*#define DExpandChain(x,y) DEBUGFUNC \
580 jtmfs_expandchain(x,y)*/
581#define DExpandChain jtmfs_expandchain
582
583//
584int jtmfs_expandchain(int device_nr,int amount);
585
586// JTMFS_FILE_ENTRY
587#include "jtmfsfe.h"
588
589// DIRWALK structure
590#include "fswalk.h"
591
592//
593#include "jtmfsAccess.h"
594
595//
596int jtmfs_deletechain(int device_nr,int blocknr);
597void jtmfs_inc_try(void);
598void jtmfs_init_try(void);
599void jtmfs_ffupdatefe(DIRWALK *dw);
600
601int jtmfs_fentry( JTMFS_FILE_ENTRY *e,
602 const char *name,
603 unsigned short int type,
604 unsigned int length,
605 unsigned char protection,
606 unsigned char owner,
607 unsigned int creationdate,
608 unsigned int lastaccessdate,
609 unsigned int lastchangedate,
610 unsigned int FirstDataBlock,
611 unsigned int LastDataBlock);
612
613int jtmfs_ffindfile(int device_nr,const char *fname,int block_nr,DIRWALK *dw);
614int jtmfs_cedir(JTMFS_FILE_ENTRY *e,const char *name,
615 int FirstDataBlock,int LastDataBlock);
616void jtmfs_cedirend(JTMFS_FILE_ENTRY *);
617int jtmfs_createdirectory(int device_nr,int dirblock, int backdb,
618 const char *name);
619int jtmfs_getrootdir(int device_nr);
620int jtmfs_createrootdir(int device_nr);
621int jtmfs_formatdrive(int device_nr);
622int jtmfs_dirroot(int device_nr);
623int jtmfs_ffIsLast(int device_nr,DIRWALK *);
624int jtmfs_clearwbuf(int device_nr,DIRWALK *);
625int jtmfs_ffreadlocation(int device_nr,DIRWALK *);
626int jtmfs_ffwritelocation(int device_nr,DIRWALK *);
627int jtmfs_addentry(int device_nr,
628 int,JTMFS_FILE_ENTRY *);
629void EndDirWalk(DIRWALK *dw);
630int jtmfs_getfilesize(int device_nr,const char *fname,int dblock);
631int jtmfs_getfileblocksize(int device_nr,const char *fname,int dblock);
632void InitDW(DIRWALK *dw);
633int jtmfs_fexist(int dnr,char *fname,int dblock);
634int jtmfs_renamefile(int device_nr,
635 const char *OldName, const char *NewName,
636 int dirblock);
637int jtmfs_setsize(int device_nr,
638 const char *OldName, int newSize,
639 int dirblock);
640int jtmfs_entryIsDeleted(JTMFS_FILE_ENTRY *fe);
641
642//
643#include "dir.h"
644
645#endif
646
647
648/*********************************************************************************/
649/* FILE */
650/*********************************************************************************/
651
652//
653#ifndef __INCLUDED_JTMFSFE_H__
654#define __INCLUDED_JTMFSFE_H__
655
656//
657#include "basdef.h"
658
659// 50 bytes
660typedef struct
661{
662 // 33 characters max. per file name + zero char.
663 char name[34];
664 // Health indicator.
665 DWORD magicNumber; // 0xFCE2E37B
666 // File type.
667 WORD type;
668 // Length of file, -1 means deleted entry(aka ghost).
669 int length;
670 // First data block(FAT chain).
671 DWORD FirstDataBlock;
672 // Last data block(FAT chain).
673 DWORD LastDataBlock;
674}JTMFS_FILE_ENTRY;
675
676// Some parameters not implemented at this time.
677/* // File protection
678// DWORD protection;
679 // Owner
680// BYTE owner;
681 // Creation date
682// DWORD creationdate;
683 // Last access date
684// DWORD lastaccessdate;
685 // Last change date
686// DWORD lastchangedate;*/
687
688/*
689//
690typedef struct
691{
692 // 32 bytes, so max. length is 31 characters :
693 char name[20];
694// DWORD nameChecksum32; // used for hash table
695 WORD type;
696 DWORD length;
697 DWORD protection;
698 BYTE owner;
699 DWORD creationdate;
700 DWORD lastaccessdate;
701 DWORD lastchangedate;
702 DWORD FirstDataBlock;
703 DWORD LastDataBlock;
704 BYTE unused;
705}JTMFS_FILE_ENTRY;
706*/
707
708#endif
709
710
711
712#endif
713
714/*********************************************************************************/
715/* FILE */
716/*********************************************************************************/
717#ifndef __INCLUDED_WRITEDIR_H__
718#define __INCLUDED_WRITEDIR_H__
719
720int writeDir(DIR *d);
721
722#endif
723
724
725/*********************************************************************************/
726/* FILE */
727/*********************************************************************************/
728
729/******************************************************************************************************************/
730// JTMOS FILE SYSTEM NEW MILLENIUM
731// (C) 2003,2006-2019 by Jari Tapio Tuominen (jari.t.tuominen@gmail.com MAIL)
732/******************************************************************************************************************/
733#include "kernel32.h"
734#include "dirdb.h" // DIRDB main header file
735#include "dirdbAccess.h" // DIRDB access functions
736#include "dirdbWalk.h" // DIRDB dir walking functions
737#include "writeDir.h"
738
739#include "sysmem.h"
740#include "macrodef.h"
741#include "int.h"
742#include "pit.h"
743#include "keyb.h"
744#include "syssh.h"
745#include "cmos.h"
746#include "floppy.h"
747#include "buildnr.h"
748// ---- #include "fileapi.h"
749#include "ramdisk.h"
750#include "jtmfs.h"
751#include "fswalk.h"
752#include "fsadd.h"
753#include "fsdos.h"
754#include "fname_translation.h"
755#include "jtmfsAccess.h"
756#include "jtmfsAccessInit.h"
757//
758#include "kernel32.h"
759#include "rtc.h"
760#include "macrodef.h"
761#include "int.h"
762#include "pit.h"
763#include "keyb.h"
764#include "syssh.h"
765#include "cmos.h"
766#include "floppy.h"
767#include "buildnr.h"
768//
769#include "jtmfs.h"
770// ---- #include "fileapi.h"
771#include "ramdisk.h"
772#include "jtmfat.h"
773//
774#include "jtmfs.h"
775#include "jtmfat.h"
776#include "flexFat.h"
777#include "format.h"
778
779
780#include "sysmem.h"
781#include "macrodef.h"
782#include "int.h"
783#include "pit.h"
784#include "keyb.h"
785#include "syssh.h"
786#include "cmos.h"
787#include "floppy.h"
788#include "buildnr.h"
789// ---- #include "fileapi.h"
790#include "ramdisk.h"
791#include "jtmfs.h"
792#include "fswalk.h"
793#include "fsadd.h"
794#include "fsdos.h"
795#include "fname_translation.h"
796//
797#include "flexFat.h"
798#include "flexCorruption.h" // corruption checks
799
800#include "kernel32.h"
801#include "dirdb.h" // DIRDB main header file
802#include "dirdbAccess.h" // DIRDB access functions
803#include "dirdbWalk.h" // DIRDB dir walking functions
804#include "writeDir.h"
805//
806DIRDB dirdb;
807
808//
809int dirdb_inited=0;
810
811//
812char flextmp[256];
813
814// Flex FAT main structure
815FLEFATSYS *fle;
816int flexActive=FALSE;
817
818//
819int findfreeblock_last_block_nr=-1,
820 EntranceGetrootdir=0;
821//
822char *TMPSPACE1=NULL, *BOOT_TMP_BUF=NULL;
823//
824JTMFATSYS *fatsys;
825// Set to TRUE after jtmfat is ready to be used
826int jtmfat_ready=FALSE;
827//
828USE_DEBUGTRAP
829
830
831// ======================================================================
832// Enhanced directory cache database system,
833// aka EDCDS system.
834// (C) 2002-2005 by Jari Tuominen.
835//
836// This file contains only the init routine
837// and some few functions.
838// Other functions are located in seperate
839// dirdb* files.
840// ======================================================================
841
842
843//================================================================
844// writeDir.c
845// part of DirDB
846//================================================================
847//
848DIRDB dirdb;
849
850//
851int dirdb_inited=0;
852
853//
854void pause(const char *s)
855{
856 printk(s);
857 ESCLOCK();
858}
859
860// Initialise DIRDB
861int dirdb_init(void)
862{
863 // --------------------------------------
864 int i,i2,i3,i4;
865
866 //
867 if(dirdb_inited)return 1;
868 dirdb_inited = 1;
869
870 // --------------------------------------
871 // Clear structure
872 memset(&dirdb, 0, sizeof(DIRDB));
873
874 // Set amount of directories in cache
875 dirdb.total = MAX_DIRS_CACHED;
876
877 // Set entries amount to zero
878 dirdb.n_entries = 0;
879
880 // Set state to free(for concurrency handling)
881 dirdb.state = 0;
882
883 // Set all directory entries free
884 for(i=0; i<dirdb.total; i++)
885 {
886 // Set guard variable
887 dirdb.dir[i].guard = DIRDB_GUARD;
888 // Set entry free
889 dirdb.dir[i].isfree = 1;
890 // Allocate data for dir data buffer
891 dirdb.dir[i].buf = malloc(MAX_BYTES_PER_DIR);
892 dirdb.dir[i].l_buf = MAX_BYTES_PER_DIR;
893 // Set type to directory
894 dirdb.dir[i].type = ID_DIRECTORY;
895* }
896
897 // No cache flush request at the start up.
898 dirdb.cacheFlushRec = 0;
899
900 //
901 return 0;
902}
903-
904
905/*********************************************************************************/
906/* FILE */
907/*********************************************************************************/
908
909// Write directory on drive
910// (Used by flush function - For cache system only.)
911// Return value:
912// 0 on success
913// non-zero on error
914int writeDir(DIR *d)
915{
916 int blocks,x,er;
917 static char str[256];
918 static BYTE *tmp;
919 static int l_tmp;
920
921 //
922 DIRDEBUG
923
924 //
925 if(d==NULL)
926 return 1;
927
928 // Determine amount of blocks to write
929 if(d->type==ID_DIRECTORY)
930 {
931 d->n_entries = countEntries(d);
932 blocks = sizeof(JTMFS_FILE_ENTRY)*d->n_entries/getblocksize(d->dnr);
933 blocks++;
934 }
935 else
936 // ...
937 if(d->type==ID_FILE)
938 {
939 //
940 blocks = d->blocks;
941
942 //
943 printk("%s: Writing file dnr=%d, db=%d, buf=0x%x.\n",
944 __FUNCTION__,
945 d->dnr, d->db,
946 d->buf);
947 }
948 else
949 {
950 // Unknown type.....
951 printf("%s: Unknown DIR->type -type (%d).\n",
952 __FUNCTION__, d->type);
953 return 300;
954 }
955
956 // Determine amount of entries directory has
957 if(d->type==JTMFS_ID_DIRECTORY)
958 {
959 //
960 printk("%s: Writing directory dnr=%d, db=%d, buf=0x%x.\n",
961 __FUNCTION__,
962 d->dnr, d->db,
963 d->buf);
964
965 //
966 d->n_entries = countEntries(d);
967 // Inform
968 devsys_getdevicename(d->dnr, str);
969 printk("%s: Writing directory on drive %s:\n(%d entries detected for this directory)\n",
970 __FUNCTION__,
971 str,
972 d->n_entries);
973 }
974
975 // Allocate tmp buffer
976 l_tmp = (blocks+1)*getblocksize(d->dnr);
977 tmp = malloc(l_tmp);
978 if(tmp==NULL)
979 {
980 printf("%s: Out of memory --- blocks=%d, bs=%d\n",
981 __FUNCTION__,
982 blocks, getblocksize(d->dnr));
983 return 303;
984 }
985
986repeat:
987 //
988 printk("%s: writing %dK bytes (%d entries)\n",
989 __FUNCTION__,
990 l_tmp/1024,
991 d->n_entries);
992 //
993 // Write directory blocks on chain
994 printk("0x%x, %d,%d, %d, %d\n",
995 d->buf, d->dnr,d->db, l_tmp,0);
996 er=jtmfs_WriteFileChain(
997 d->buf, d->dnr, d->db,
998 l_tmp, 0);
999
1000 //
1001 if(er==-2)
1002 {
1003 printk("Disk full... Can't write directory.\n");
1004 return 10;
1005 }
1006 else
1007 if(er)
1008 {
1009 printk("writeDir: error %d\n", er);
1010 panic("writeDir error");
1011 }
1012
1013 // Verify
1014 jtmfs_ReadFileChain(
1015 tmp, d->dnr, d->db,
1016 l_tmp, 0);
1017
1018 // Compare
1019 for(x=0; x<l_tmp; x++)
1020 if(d->buf[x]!=tmp[x])
1021 {
1022 printf("Difference at offset 0x%x\n", x);
1023 /** printk("dirdb:\n");
1024 DisplayMemory(d->buf+x-64, 128, 0);
1025 printk("disk:\n");
1026 DisplayMemory(tmp+x-64, 128, 0); **/
1027 //getch();
1028 //goto repeat; // !!
1029 break;
1030 }
1031
1032 //
1033 free(tmp);
1034 l_tmp=0;
1035 return 0;
1036}
1037
1038
1039
1040/*********************************************************************************/
1041/* FILE */
1042/*********************************************************************************/
1043// ==================================================
1044// JTMOS FILE SYSTEM
1045// -----------------
1046//
1047// (C) 2001-2004 by Jari Tuominen
1048// (jari.tuominen@kanetti.fi).
1049//
1050// JTMFS is dependent on JTMFAT.
1051// JTMFAT is dependent on a block device,
1052// which varies.
1053// The block device is accessible via
1054// the BLOCK/CHAR DEVICE API implementation,
1055// which uses a caching system.
1056//
1057// jtmfsAccess.c FS plugins access layer(high)
1058// jtmfat.c JTMOS file allocation system(low)
1059// jtmfs.c JTMOS file system(low)
1060// fswalk.c Dir walking functions(low)
1061// fsfind.c File finding functions(low)
1062// fsadd.c Directory entry adding functions(low)
1063// fsaddblocks.c Allocate more blocks on for(low)
1064// file or directory
1065// fsdev.c Functions that figure out
1066// which device is currently
1067// assigned to each of the processes(low)
1068// ==================================================
1069
1070//----------------------------------------------------------------------
1071//
1072DEBUGSTR debugstr;
1073
1074//
1075struct
1076{
1077 int try;
1078}jtmfs_structure;
1079
1080//----------------------------------------------------------------------
1081// Called by DiskChange system function.
1082int jtmfs_DiskChange(int dnr)
1083{
1084 // Indicate boot block content change.
1085 fatsys->isJTMFS[dnr]==FALSE;
1086}
1087
1088//
1089void InitDW(DIRWALK *dw)
1090{
1091 memset(dw, 0, sizeof(DIRWALK));
1092 dw->buf_length = 8192;
1093}
1094
1095//
1096void EndDirWalk(DIRWALK *dw)
1097{
1098 //
1099 dw->isWalking=0;
1100}
1101
1102//
1103void jtmfs_inc_try(void)
1104{
1105 BYTE *dummy_buf,*dummy_buf2;
1106
1107 //
1108 jtmfs_structure.try++;
1109
1110 // print out the try number
1111 print("{"); pd32(jtmfs_structure.try); print("}");
1112
1113 // make allocation system test(see if it works at all :))
1114 dummy_buf= malloc(1024*4+4368+jtmfs_structure.try);
1115 dummy_buf2=malloc(1024*4+2352+jtmfs_structure.try);
1116 free(dummy_buf);
1117 free(dummy_buf2);
1118}
1119
1120// -----------------------------------------------------------
1121//
1122void jtmfs_init(void)
1123{
1124 //
1125 jtmfs_init_try();
1126 jtmfsAccessInit();
1127}
1128
1129// -----------------------------------------------------------
1130//
1131void jtmfs_init_try(void)
1132{
1133 jtmfs_structure.try=0;
1134}
1135
1136// -----------------------------------------------------------
1137// jtmfs_ffupdatefe
1138//
1139// Updates dw->fe to point at a correct location
1140// of dw->buf, this is done by using dw->current_offset.
1141// Updating the pointer structure makes the findfirst/next
1142// functions generally much easier to use and more efficient too.
1143//
1144void jtmfs_ffupdatefe(DIRWALK *dw)
1145{
1146 // Update offset with modern walk
1147 dw->fe = dw->d->buf+dw->current_offset;
1148
1149 // For debugging :
1150#ifdef JTMFSDEBUG
1151 dprintk("%s: dw->fe=0x%x, dw->d->buf=0x%x, dw->buf=0x%x\n",
1152 __FUNCTION__,
1153 dw->fe,
1154 dw->d->buf,
1155 dw->buf);
1156#endif
1157}
1158
1159
1160
1161/* typedef struct
1162 * {
1163 * // sizeof, bytes :
1164 * // 0x00
1165 * char name[31];
1166 * unsigned short int type;
1167 * unsigned int length; (if -1 then entry is a ghost, deleted)
1168 * unsigned int protection;
1169 * unsigned char owner;
1170 * unsigned int creationdate;
1171 * unsigned int lastaccessdate;
1172 * unsigned int lastchangedate;
1173 * unsigned int track;
1174 * unsigned int block;
1175 * // 0x40 .... bingo
1176 * //
1177 * }JTMFS_FILE_ENTRY;
1178 */
1179
1180// Use this function to create a single file/dir entry!
1181int jtmfs_fentry( JTMFS_FILE_ENTRY *e,
1182 const char *name,
1183 unsigned short int type,
1184 unsigned int length,
1185 unsigned char protection,
1186 unsigned char owner,
1187 unsigned int creationdate,
1188 unsigned int lastaccessdate,
1189 unsigned int lastchangedate,
1190 unsigned int FirstDataBlock,
1191 unsigned int LastDataBlock)
1192{
1193 // If entry is NULL:
1194 if(e==NULL || name==NULL)
1195 return 1;
1196
1197 // If filename error:
1198 if(!strlen(name) || strlen(name)>31)
1199 return 2;
1200
1201 // First wipe
1202 memset(e, 0, sizeof(JTMFS_FILE_ENTRY));
1203 // Then copy
1204 strcpy(e->name, name);
1205 e->type= type; // 0x80 = directory
1206 e->length= length; // -1 = deleted / aka ghost
1207 e->FirstDataBlock= FirstDataBlock;
1208 e->LastDataBlock= LastDataBlock;
1209 e->magicNumber= 0xFCE2E37B;
1210
1211 // Return success.
1212 return 0;
1213}
1214
1215//--------------------------------------------------------------------------------
1216//
1217// Creates a directory entry.
1218//
1219int jtmfs_cedir(JTMFS_FILE_ENTRY *e,const char *name,
1220 int FirstDataBlock,int LastDataBlock)
1221{
1222 // null reference checker
1223 if(!e || !name)
1224 {
1225 panic("[Oops!] jtmfs_cedir called with e==NULL || name==NULL\n");
1226 return;
1227 }
1228
1229 // clear structure
1230 memset(e,0,sizeof(JTMFS_FILE_ENTRY));
1231
1232 // copy name
1233 strcpy(e->name, name);
1234 e->FirstDataBlock = FirstDataBlock;
1235 e->LastDataBlock = LastDataBlock;
1236 e->magicNumber = 0xFCE2E37B;
1237
1238 // type = directory(0x80)
1239 e->type = JTMFS_ID_DIRECTORY;
1240
1241 //
1242 return 0;
1243}
1244
1245// Creates end of directory
1246void jtmfs_cedirend(JTMFS_FILE_ENTRY *e)
1247{
1248 // NULL?
1249 if(e==NULL)
1250 {
1251 panic("[Oops!] jtmfs_cedirend called with e==NULL\n");
1252 return;
1253 }
1254
1255 // Clear entry
1256 memset(e, 0, sizeof(JTMFS_FILE_ENTRY));
1257}
1258
1259// jtmfs_createdirectory
1260//
1261// dblock = block where the directory are about to be stored at
1262// This fuction writes an independent directory on the disk.
1263// It is not a subdirectory, unless otherwise specified later on.
1264//
1265// Note!: the block where the directory will be made at,
1266// MUST be free, if not so, no directory will be created.
1267//
1268int jtmfs_createdirectory(int device_nr, int dblock, int backdb,
1269 const char *name)
1270{
1271 static JTMFS_FILE_ENTRY *fe[100];
1272 static unsigned char *p;
1273 static DWORD ad;
1274 static int i,i2,i3,i4,alal;
1275 static BYTE *buf; // It gotta be atleast as big as largest possible block
1276 static int flags;
1277 static char temp[65536];
1278 char dirname[256];
1279
1280 //-----------------------------------------------------------------------------
1281 //
1282 if(!isValidDevice(device_nr)) return 10;
1283 // JTMFS required
1284 if(!jtmfat_isJTMFS(device_nr))return 1;
1285 //
1286 if( illegal(name) )
1287 panic("ILLEGAL POINTER FOR NAME STRING, CREATE DIRECTROY");
1288 if( strlen(name)<=0 )
1289 {
1290 printk("%s: name string is empty!\n",
1291 __FUNCTION__);
1292 return 1;
1293 }
1294 printk("%s: (1)\n", __FUNCTION__);
1295
1296 //-----------------------------------------------------------------------------
1297 // Get only the directory name(e.g. resolve from path string).
1298 for(i=strlen(name)-1,i2=strlen(name); i>=0 && name[i]!='/' && i2; i2--,i--);
1299 i++;
1300 strcpy(dirname, name+i);
1301
1302 //
1303 alal = 0;
1304 printk("%s: (2)\n", __FUNCTION__);
1305
1306 // --------------------------------------------------------------------
1307 dirdb_clearCacheForDB(device_nr, dblock);
1308
1309 // TODO: here we should check for the validity of the device_nr
1310 //
1311 if(jtmfat_getblock(device_nr,dblock))
1312 {
1313 //
1314 alal = 1;
1315 //panic("jtmfs_createdirectory: Oops! Attempting to create directory on already allocated block");
1316 }
1317 printk("%s: (3)\n", __FUNCTION__);
1318
1319 // Warning, this must be freed afterwards:
1320 flags=get_eflags(); disable();
1321 buf = temp;
1322 set_eflags(flags);
1323
1324 // Wipe the block buffer.
1325 // Note: I didn't do this right away, the result was that
1326 // the directory was very messy... And it messed the workability of
1327 // the entire directory mechanism... :]
1328 ReportMessage("%s: memset\n", __FUNCTION__);
1329 memset(buf, 0, 16384);
1330
1331 printk("%s: (4)\n", __FUNCTION__);
1332
1333 // init the 100 entries array
1334 ReportMessage("%s: Initializing 100 entries array.\n", __FUNCTION__);
1335 for(i=0; i<100; i++)
1336 {
1337 ad=((DWORD)buf)+i*sizeof(JTMFS_FILE_ENTRY);
1338 ((JTMFS_FILE_ENTRY*)fe[i])=((DWORD)ad);
1339 }
1340
1341 printk("%s: (5)\n", __FUNCTION__);
1342
1343 // Create few basic directory references
1344 // first last
1345 // block block
1346 ReportMessage("%s: A few cedirs...\n", __FUNCTION__);
1347 jtmfs_cedir( fe[0], ".", dblock,dblock );
1348 jtmfs_cedir( fe[1], "..", backdb,backdb );
1349 // Add directory name into directory.
1350 jtmfs_cedir( fe[2], dirname, 0,0 );
1351 fe[2]->type = JTMFS_ID_DIRNAME;
1352 fe[2]->length = -1;
1353 // Set end of directory.
1354 jtmfs_cedirend(fe[3]);
1355
1356 printk("%s: (6)\n", __FUNCTION__);
1357
1358 // Write on the drive
1359 printk("%s: writeblock(%d,%d, %x)\n", __FUNCTION__, device_nr,dblock,buf);
1360 writeblock(device_nr, dblock, buf);
1361 printk("%s: Done.\n", __FUNCTION__);
1362
1363 printk("%s: (7)\n", __FUNCTION__);
1364
1365 //
1366 ReportMessage("%s: setblock\n", __FUNCTION__);
1367 // Allocate it to the FAT(End of chain, so which means
1368 // that there is no next block)
1369 if(!alal)
1370 jtmfat_setblock(device_nr,dblock, 0xFFFFFFF8);
1371 ReportMessage("%s: Done.\n", __FUNCTION__);
1372
1373
1374 printk("%s: (8)\n", __FUNCTION__);
1375
1376
1377 //
1378 return 0;
1379}
1380
1381//
1382int jtmfs_getrootdir(int device_nr)
1383{
1384 if(!isValidDevice(device_nr)) return 0;
1385
1386 // We will just pass this request for the JTMFAT
1387 // (JTMFAT nowadays does this stuff).
1388 return jtmfat_getrootdir(device_nr);
1389}
1390
1391// Create root directory(used by formatdrive)
1392int jtmfs_createrootdir(int dnr)
1393{
1394 int rdnr;
1395 char *str_root="/";
1396
1397 // Device validity check
1398 if(!isValidDevice(dnr))
1399 {
1400 printk("%s: DNR %d is not a valid device!",
1401 __FUNCTION__, dnr);
1402 return 2;
1403 }
1404 // JTMFS required
1405 if(!jtmfat_isJTMFS(dnr))
1406 {
1407 printk("%s: DNR %d is not formatted! Cannot create directory.",
1408 __FUNCTION__, dnr);
1409 return 1;
1410 }
1411
1412 // Get root directory block #
1413 rdnr = jtmfs_getrootdir(dnr);
1414 // Root directory block validity check
1415 if(rdnr<=0)
1416 {
1417 printk("%s: Illegal root dir block = %d!\n",
1418 __FUNCTION__, rdnr);
1419 }
1420 else
1421 {
1422 // Create root directory
1423 printk("%s: Root dir block = %d\n",
1424 __FUNCTION__, rdnr);
1425 printk("%s: Creating directory on it:\n", __FUNCTION__);
1426 jtmfs_createdirectory(dnr, rdnr, 0, str_root);
1427 printk("%s: Directory creation completed.\n", __FUNCTION__);
1428 }
1429 return 0;
1430}
1431
1432// Lists root directory's contents
1433int jtmfs_dirroot(int device_nr)
1434{
1435 if(!isValidDevice(device_nr)) return 1;
1436
1437 // JTMFS required
1438 //
1439 jtmfs_dir( device_nr, jtmfs_getrootdir(device_nr) );
1440
1441 //
1442 return 0;
1443}
1444
1445// Checks if it is the last entry?
1446// Return value: non-zero if true, else zero
1447int jtmfs_ffIsLast(int device_nr,DIRWALK *dw)
1448{
1449 // JTMFS required
1450 if(!jtmfat_isJTMFS(device_nr))return 1;
1451
1452 //
1453 if( !strlen(dw->fe->name) ) return 1;
1454
1455 //
1456 return 0;
1457}
1458
1459int jtmfs_clearwbuf(int device_nr,DIRWALK *dw)
1460{
1461 //
1462 return 0;
1463}
1464
1465// EXPAND FILE OR DIRECTORY CHAIN
1466// ------------------------------
1467//
1468// This function expands a file chain, so that it will contain
1469// one more block.
1470// Return value: new block's number
1471// Negative value means error.
1472//
1473int jtmfs_expandchain(int device_nr,int block)
1474{
1475 int new_block;
1476
1477 // JTMFS required
1478 if(!jtmfat_isJTMFS(device_nr))return -1;
1479
1480 // TODO: make a device_nr validity check here
1481 if(1)
1482 {
1483 //
1484 ReportMessage(">");
1485
1486 // Is 'block' the last block in the chain?
1487 // not?->error
1488 if( jtmfat_getblock(device_nr, block)!=0xfffffff8 )
1489 {
1490 //
1491 DEBUGINFO
1492 dprintk("jtmfs_expandchain: error, the offered block is not last one in the chain\n");
1493 return -2;
1494 }
1495 else
1496 {
1497 // Get a new free block
1498 new_block = jtmfat_getfreeblock(device_nr);
1499
1500 //
1501 if(!new_block)
1502 {
1503 DEBUGINFO
1504 dprintk("jtmfs_expandchain: Out of disk space.\n");
1505 return -3;
1506 }
1507
1508 //
1509 if(new_block == block)
1510 {
1511 DEBUGINFO
1512 dprintk("jtmfs_expandchain error: new_block(%d) == block(%d).\n",new_block,block);
1513 dprintk("Perhaps this is a logic error in jtmfat_getfreeblock().\n");
1514 panic("oops");
1515 }
1516
1517 // Set 'block' to continue at 'new_block'
1518 jtmfat_setblock(device_nr, block,new_block);
1519 if( jtmfat_getblock(device_nr,block)!=new_block )
1520 {
1521 DEBUGINFO
1522 dprintk("jtmfs_expandchain: fatset failed.\n");
1523 return -6;
1524 }
1525
1526 // Then set 'end of chain marking' of chain at the 'new_block'
1527 jtmfat_setblock(device_nr,new_block, 0xFFFFFFF8);
1528
1529 //
1530 if( jtmfat_getblock(device_nr,block)!=new_block )
1531 {
1532 DEBUGINFO
1533 panic("jtmfs_expandchain: fatset failed.\n");
1534 return -4;
1535 }
1536
1537 //
1538 return new_block;
1539 }
1540 }
1541 else
1542 {
1543 DEBUGINFO
1544 print("jtmfs_expandchain: fatal error\n");
1545 return -5;
1546 }
1547
1548 //
1549 return 0;
1550}
1551
1552// Reads current block location at the buffer
1553// I tried to optimize it to load only when neccesary,
1554// but it didn't really work right :\
1555// TODO: WHY it is needed to load the block everytime?
1556int jtmfs_ffreadlocation(int device_nr,DIRWALK *dw)
1557{
1558 // JTMFS required
1559 if(!jtmfat_isJTMFS(device_nr))return 1;
1560
1561 //
1562 if(dw)
1563 {
1564 if(dw->isWalking)
1565 dirdb_flushRequirement(dw);
1566 }
1567
1568 //
1569 return 0;
1570}
1571
1572// Writes current buffer to the disk
1573int jtmfs_ffwritelocation(int device_nr, DIRWALK *dw)
1574{
1575 // JTMFS required
1576 if(!jtmfat_isJTMFS(device_nr))
1577 {
1578 dprintk("%s: DNR%d = non-JTMFS file system\n",
1579 __FUNCTION__, device_nr);
1580 return 1;
1581 }
1582
1583 //
1584 if(dw!=NULL)
1585 {
1586 dirdb_flushRequirement(dw);
1587 }
1588 else
1589 {
1590 dprintk("%s: ERROR Called with dw==NULL\n",
1591 __FUNCTION__);
1592 }
1593
1594 //
1595 return 0;
1596}
1597
1598/* typedef struct
1599 * {
1600 * // sizeof, bytes :
1601 * // 0x00
1602 * 00 char name[31];
1603 * 20 unsigned short int type;
1604 * 22 unsigned int length;
1605 * 26 unsigned int protection;
1606 * 2a unsigned char owner;
1607 * 2b unsigned int creationdate;
1608 * 2f unsigned int lastaccessdate;
1609 * 33 unsigned int lastchangedate;
1610 * 37 unsigned int track;
1611 * 3b unsigned int block;
1612 * 3f unsigned char unused;
1613 * // 0x40 .... bingo
1614 * //
1615 * }JTMFS_FILE_ENTRY;
1616 */
1617
1618//
1619int jtmfs_entryIsDeleted(JTMFS_FILE_ENTRY *fe)
1620{
1621 if(fe->length==-1)
1622 return 1;
1623 else
1624 return 0;
1625}
1626
1627// jtmfs_deletefile dnr,fname,dirblock
1628// -----------------------------------
1629//
1630// Sets the direntry of the specified file as "free",
1631// and frees all blocks that are allocated by the file,
1632// if any.
1633//
1634// New: if dirblock equals to zero, it'll be treated as
1635// the rootdirectory(default).
1636//
1637int jtmfs_deletefile(int device_nr,const char *fname,int dirblock)
1638{
1639 static DIRWALK dw;
1640 static int delete_blocknr;
1641 static int dirblock1;
1642
1643 // Sanity check
1644 if(dirblock>=getsize(device_nr))return 1;
1645
1646 // Get fixed dirblock
1647 // If dirblock is zero, get the root directory(default).
1648 if(!dirblock)
1649 dirblock1 = jtmfs_getrootdir(device_nr);
1650 else
1651 dirblock1 = dirblock;
1652
1653 //
1654 InitDW(&dw);
1655
1656 // Find the file
1657 if( !jtmfs_ffindfile(device_nr,fname,dirblock1,&dw) )
1658 {
1659 // Not found?
1660 // Note: Heh, dir walk won't be ended when it has not even started!
1661 //// EndDirWalk(&dw);
1662 return 1;
1663 }
1664
1665 // After 'ffindfile' dirblock* parameter will be not used.
1666 // Instead the structure 'fe' will be used. If any data is
1667 // allocated.
1668 if(dw.fe->FirstDataBlock)
1669 {
1670 //
1671 delete_blocknr = dw.fe->FirstDataBlock;
1672
1673 // --- Currently the deletchain seems not to work properly ---
1674 // Try to delete the chain as we are now deleting the file
1675 if( jtmfs_deletechain(device_nr,delete_blocknr) )
1676 {
1677 //
1678 EndDirWalk(&dw);
1679 // Return non-zero if not succeeded
1680 return 2;
1681 }
1682 }
1683
1684 // At this point the file should not have any reserved blocks,
1685 // so we can set the directory entry as free as well.
1686 //
1687 // Remove the entry from the directory
1688 // This is done by setting the file's length to minus one(-1).
1689 //
1690 dw.fe->length = -1;
1691
1692 // Then we write the block back.
1693 jtmfs_ffwritelocation(device_nr,&dw);
1694
1695 //
1696 EndDirWalk(&dw);
1697
1698 // We're clear!
1699 return 0;
1700}
1701
1702// ------------------------------------------------------------------------------
1703// jtmfs_renamefile(dev, "floppy:lala", "lolo", rootdir);
1704//
1705// Renames a file or files.
1706// REN [drive:][path]filename1 filename2.
1707// Note that you cannot specify a new drive or path for your destination file.
1708//
1709int jtmfs_renamefile(int device_nr,
1710 const char *OldName, const char *NewName,
1711 int dirblock)
1712{
1713 static DIRWALK dw;
1714 static int delete_blocknr;
1715 static int dirblock1;
1716
1717 // Sanity check
1718 if(dirblock>=getsize(device_nr))return 1;
1719
1720 // Get fixed dirblock
1721 // If dirblock is zero, get the root directory(default).
1722 if(!dirblock)
1723 dirblock1 = jtmfs_getrootdir(device_nr);
1724 else
1725 dirblock1 = dirblock;
1726
1727 //
1728 InitDW(&dw);
1729
1730 // Find the file
1731 if( !jtmfs_ffindfile(device_nr,OldName,dirblock1,&dw) )
1732 {
1733 // Not found?
1734 // Note: Heh, dir walk won't be ended when it has not even started!
1735 //// EndDirWalk(&dw);
1736 return 1;
1737 }
1738
1739 // MODIFY FILE NAME
1740 //
1741 strcpy(dw.fe->name, NewName);
1742
1743 // Then we write the block back.
1744 jtmfs_ffwritelocation(device_nr,&dw);
1745
1746 //
1747 EndDirWalk(&dw);
1748
1749 // We're clear!
1750 return 0;
1751}
1752
1753// ------------------------------------------------------------------------------
1754// jtmfs_setsize(dev, "floppy:lala", new_size, rootdir);
1755//
1756// Set file fixed size (in bytes).
1757//
1758// This function only sets the visible size, but does
1759// not affect the real allocated blocks amount.
1760//
1761int jtmfs_setsize(int device_nr,
1762 const char *OldName, int newSize,
1763 int dirblock)
1764{
1765 DIRWALK dw;
1766 int delete_blocknr;
1767 int dirblock1;
1768
1769 // Sanity check
1770 if(dirblock>=getsize(device_nr))return 1;
1771
1772 // Get fixed dirblock
1773 // If dirblock is zero, get the root directory(default).
1774 if(!dirblock)
1775 dirblock1 = jtmfs_getrootdir(device_nr);
1776 else
1777 dirblock1 = dirblock;
1778
1779 //
1780 InitDW(&dw);
1781
1782 // Find the file
1783 if( !jtmfs_ffindfile(device_nr, OldName, dirblock1, &dw) )
1784 {
1785 // Not found?
1786 // Note: Heh, dir walk won't be ended when it has not even started!
1787 //// EndDirWalk(&dw);
1788 printf("%s: file not found '%s'\n",
1789 __FUNCTION__, OldName);
1790 return 1;
1791 }
1792
1793 // MODIFY FILE NAME
1794 //
1795 dw.fe->length = newSize;
1796
1797 //
1798 ReportMessage("%s: '%s': File size set to %d bytes.\n",
1799 __FUNCTION__, OldName, dw.fe->length);
1800
1801 // Then we write the block back.
1802 jtmfs_ffwritelocation(device_nr, &dw);
1803
1804 //
1805 EndDirWalk(&dw);
1806
1807 // We're clear!
1808 return 0;
1809}
1810
1811// DELETECHAIN
1812// -----------
1813//
1814// Deletes a file/dir chain
1815// (frees all the blocks of the specified chain)
1816//
1817// Returns zero on success
1818// and non-zero on error
1819//
1820// NEW: now ignores chain that is allocated on block zero.
1821//
1822// ** TODO **
1823// Something wrong here, it does not delete the chain.
1824// Instead the data is left there, maybe
1825// dump of the fat table will tell what has
1826// been happended.
1827// But it definetly does not deallocate the chain.
1828//
1829int jtmfs_deletechain(int device_nr, int blocknr)
1830{
1831 DWORD i,i2,i3,i4,b,block,first;
1832
1833 // Sanity check
1834 if(blocknr>=getsize(device_nr))return 1;
1835
1836 //
1837 for(block=blocknr,first=1; ; )
1838 {
1839 // Check if the block is the last block
1840 if( (b=jtmfat_getblock(device_nr,block))==0xfffffff8 )
1841 {
1842 jtmfat_setblock(device_nr,block,0);
1843 return 0;
1844 }
1845
1846 // Nothing allocated?(First block on chain and zero block reference)
1847 if(first && !b)
1848 {
1849 dprintk("jtmfs_deletechain: nothing allocated, block=%d, blocknr=%d, b=%d, first=%d\n",
1850 block,blocknr,b,first);
1851 return 1;
1852 }
1853
1854 //
1855 first=0;
1856
1857 // Unexpected code?
1858 if(b>=0xfffffff0)
1859 {
1860 dprintk("deletechain: FAT integrity error, unexpected F-code");
1861 dsleep(1);
1862 //waitkey();
1863 }
1864
1865 // Jump to itself?
1866 if(b==block)
1867 {
1868 dprintk("deletechain: FAT integrity error infinite jump %d => %d\n",b,block);
1869 dsleep(1);
1870 return 1;
1871 }
1872
1873 // Free first block
1874 jtmfat_setblock(device_nr,block,0);
1875
1876 // Jump to next block on chian
1877 block=b;
1878 }
1879
1880 //
1881 return 0;
1882}
1883
1884// The real getfilesize function.
1885// Returns size of the file in bytes.
1886//
1887int jtmfs_getfilesize(int dnr, const char *fname, int db)
1888{
1889 static DIRWALK dw;
1890
1891 // Find the file
1892 if( !jtmfs_ffindfile(dnr,fname,db,&dw) )
1893 {
1894 return -1;
1895 }
1896
1897 return dw.fe->length;
1898}
1899
1900// Returns size of the specified file.
1901//
1902// PERFORMANCE NOTIFICATION:
1903// This is a determistic diagnostics function and it is SLOW.
1904// It is easier to just read the file entry and use it's
1905// file size identifier variable to determine size of the file.
1906//
1907int jtmfs_getfileblocksize(int device_nr, const char *fname, int dblock)
1908{
1909 static DWORD i,i2,i3,i4,db,block,new_block,amount_to_allocate,amount;
1910 static DIRWALK dw;
1911
1912 // Find the file
1913 if( !jtmfs_ffindfile(device_nr,fname,dblock,&dw) )
1914 {
1915 // Not found? HEH! RETURN ZERO IF NOT FOUND.
1916 // We simply can't return other.
1917 return 0;
1918 }
1919
1920 // Get location of the data
1921 block = dw.fe->FirstDataBlock;
1922
1923 // No data block? => return size 0
1924 if(!block)return 0;
1925
1926 // BLOCK WALK CODE
1927 // Walk until we are at the end of the chain
1928 for(amount=1; ; amount++)
1929 {
1930 //
1931 db=jtmfat_getblock(device_nr,block);
1932
1933 // End of chain? => break
1934 if(db==0xFFFFFFF8)break;
1935 // Reserved area? => break(Error situation really!)
1936 if(db==0xFFFFFFF7)break;
1937 //
1938 if(db>=0xFFFFFFF0)
1939 {
1940 dprintk("FAT error in chain(media failure?)\n");
1941 dprintk("jtmfs_getfilesize: error, unknown FAT value(0x%x) on block %d\n",db,block);
1942 dsleep(1);
1943// waitkey();
1944 EndDirWalk(&dw);
1945 return 2;
1946 }
1947 if(db==block)
1948 {
1949 dprintk("FAT error in chain(media failure?)\n");
1950 dprintk("jtmfs_getfilesize: infinite jump to itself(FAT)\n");
1951 dsleep(1);
1952// waitkey();
1953 EndDirWalk(&dw);
1954 return 3;
1955 }
1956
1957 //
1958 block=db;
1959 }
1960
1961 //
1962 EndDirWalk(&dw);
1963
1964 //
1965 return amount;
1966}
1967
1968// Return value:
1969// 0 = Entry not found.
1970// 1 = Entry found(FILE).
1971// 2 = Entry found(DIRECTORY).
1972int jtmfs_fexist(int dnr, char *fname, int dblock)
1973{
1974 static DIRWALK dw;
1975 int rv;
1976
1977 //
1978 InitDW(&dw);
1979
1980 // Is it a device name?
1981 if( devsys_getdevicenrbyname(fname)!=-1 )
1982 {
1983 // Describe it as a directory:
1984 return 2;
1985 }
1986
1987 //
1988 if( jtmfs_ffindfile(dnr, fname, dblock, &dw) )
1989 {
1990 // Determine return value upon entry type
1991 switch(dw.fe->type)
1992 {
1993 // DIRECTORY
1994 case JTMFS_ID_DIRECTORY:
1995 rv = 2;
1996 break;
1997
1998 // DIRNAME
1999 case JTMFS_ID_DIRNAME:
2000 rv = 3;
2001 break;
2002
2003 // FILE
2004 default:
2005 rv = 1;
2006 break;
2007 }
2008
2009 //
2010 EndDirWalk(&dw);
2011 return rv;
2012 }
2013 else return 0;
2014}
2015
2016//
2017
2018
2019/*********************************************************************************/
2020/* FILE */
2021/*********************************************************************************/
2022/*
2023 * ========================================================================
2024 * jtmfat.c - JTMOS FAT is part of the JTMOS File System(JTMFS) package
2025 * This file contains only parts of JTMFAT, see flexFat.* for more.
2026 * (C) 2001-2005 by Jari Tuominen(jari.tuominen@kanetti.fi).
2027 * ========================================================================
2028 */
2029
2030/*
2031 * [FAT] (FILE ALLOCATION TABLE)
2032 * |
2033 * V
2034 * [DATA AREA] (FILESYSTEM/OTHER DATA)
2035 *
2036 *
2037 *
2038 * FAT TABLE(32-bit)
2039 *
2040 * 00000000 empty place
2041 * FFFFFFF1-FFFFFFF6 bad track marking
2042 * FFFFFFF7 system reserved area(BOOTSECTOR & FAT ..)
2043 * FFFFFFF8 used to mark end of a file chain
2044 * FFFFFFFF standard marker for end of a file chain
2045 * (!) Last cluster of a file always
2046 * contains a value of FFFFFFF8-FFFFFFFF.
2047 *
2048 * Ramdisks have got a standard sector
2049 * size of 1KB, 3.5" 1.44M floppys 512(�KB) bytes.
2050 */
2051
2052
2053//
2054void DebugTrap(int dnr, const char *funcStr)
2055{
2056 char *str,*str2;
2057 int i,i2;
2058 BYTE *p;
2059
2060 //
2061}
2062
2063// Calculate 32-bit checksum out of the whole FAT table
2064DWORD GetFATChecksum32(CFAT *f)
2065{
2066 int i,i2,l;
2067 BYTE *p;
2068 DWORD sum;
2069
2070 //
2071 p = f->buf; l = f->l_buf;
2072 for(i=0,sum=0; i<l; i++) { sum+=(p[i]+1); }
2073 return sum;
2074}
2075
2076// 0 = OK
2077// 1 = ERROR
2078// OTHER NUMBERS = MISC. ERROR
2079int read_fat(int dnr)
2080{
2081 //
2082 DEBUGLINE
2083 return 0;
2084}
2085
2086// Called by kernel cache flusher process only!:
2087int write_fat(int dnr)
2088{
2089 //
2090 return 0;
2091}
2092
2093int allocate_fat(int dnr)
2094{
2095 //
2096 return 0;
2097}
2098
2099// Touch on FAT it becomes alive...
2100int touch_fat(int dnr)
2101{
2102 //
2103 return 0;
2104}
2105
2106// HAS TO BE CALLED FIRST BEFORE USING JTMFAT
2107int jtmfat_init(void)
2108{
2109 static int i,i2,i3,i4;
2110
2111
2112 //
2113 if(TMPSPACE1==NULL) TMPSPACE1 = malloc(1024*64);
2114
2115 //
2116 DEBUGLINE
2117
2118 // ----------------------------------------------
2119 // GENERIC INIT
2120 // ----------------------------------------------
2121 //
2122 fatsys = malloc(sizeof(JTMFATSYS));
2123 //
2124 fatsys->virgin=1;
2125 SetMemoryName(fatsys, "fatsys:structure");
2126
2127 // Clear all the heck out first, clear table
2128 memset((void*)fatsys, 0, sizeof(JTMFATSYS));
2129
2130
2131
2132 // --------------------------------------------------------------
2133 //
2134 //
2135 dprintk("%s: Allocating sector buffers for all block devices:\n",
2136 __FUNCTION__);
2137 for(i=0; i<devsys_nr(); i++)
2138 {
2139 // This is a block device?
2140 if(getsize(i)>=1)
2141 {
2142 fatsys->bb[i] = malloc(1024*32);
2143 }
2144 }
2145 dprintk("%s: Sector buffer allocation (COMPLETED OK).\n",
2146 __FUNCTION__);
2147
2148 // ----------------------------------------------
2149 //
2150 // Temporary buffer
2151 //
2152 fatsys->tbuf = malloc(1024*64);
2153 SetMemoryName(fatsys->tbuf, "fatsys:tbuf");
2154 // ----------------------------------------------
2155
2156 // Now we enable the jtmfat, after this, calls will work.
2157 jtmfat_ready=TRUE;
2158
2159 // Init FlexFAT
2160 flexFatInit();
2161
2162 //
2163// addPitHandler(jtmfatChecker);
2164}
2165
2166// Updates info block for the drive
2167// (loads a new one from drive to the drive's info block buffer).
2168int jtmfat_LoadNewInfoBlock(int dnr)
2169{
2170 void *tmp,*p;
2171 int i,i2,i3;
2172
2173 // Allocate on demand.
2174 if(fatsys->bb[dnr]==NULL)
2175 {
2176 //
2177 fatsys->bb[dnr] = malloc(getblocksize(dnr));
2178 }
2179
2180 //
2181 tmp = TMPSPACE1;
2182 //
2183 ReportMessage("%s: Reading updated info block from drive %d.\n",
2184 __FUNCTION__, dnr);
2185 // Read info block(first block on the block device).
2186 readblock(dnr, FAT_INFO_BLOCK_OFFS/getblocksize(dnr), tmp);
2187
2188 // Copy the info part to storage.
2189 p = fatsys->bb[dnr];
2190 i2 = sizeof(JTMFAT_INFOBLOCK);
2191 i3 = FAT_INFO_BLOCK_OFFS%getblocksize(dnr);
2192 memcpy(p, tmp+i3, i2);
2193
2194 // Here here.
2195 if( !strncmp(fatsys->bb[dnr]->detstr, "JTMFS", 5) )
2196 {
2197 printk("Block device #%d is not JTMFS-formatted.\n",
2198 dnr);
2199 fatsys->isJTMFS[dnr] = TRUE;
2200 }
2201 else
2202 fatsys->isJTMFS[dnr] = FALSE;
2203
2204 //
2205 return 0;
2206}
2207
2208// Loads up data to fatsys->bb[dnr]
2209// Returns non-zero if the drive is not
2210// JTMFS formatted.
2211int _jtmfat_loadinfoblock(const char *caller, int dnr)
2212{
2213 static BYTE *tmp,*p;
2214 static int i,i2;
2215
2216 //
2217 dprintk("%s was called by %s\n",
2218 __FUNCTION__, caller);
2219 DEBUGLINE
2220
2221 //------------------------------------------------------
2222 // FAT system must be active
2223 if(jtmfat_ready!=TRUE)return 1;
2224
2225 //------------------------------------------------------
2226 // Check device
2227 if(!isValidDevice(dnr))
2228 {
2229 printk("%s: Invalid device %d.\n",
2230 __FUNCTION__, dnr);
2231 return 2;
2232 }
2233
2234 //------------------------------------------------------
2235 // Get temporary data buffer PTR
2236 tmp = TMPSPACE1;
2237 if(tmp==NULL)
2238 panic("loadinfoblock TMPSPACE1==NULL.");
2239
2240 // Allocate on demand
2241 if(fatsys->bb[dnr]==NULL)
2242 {
2243 //
2244 jtmfat_LoadNewInfoBlock(dnr);
2245 }
2246
2247 //
2248 dprintk("%s: Leaving this function.\n",
2249 __FUNCTION__);
2250 return fatsys->isJTMFS[dnr];
2251}
2252
2253// Return value:
2254// Non-zero=Success, 0=Failure
2255//
2256int _jtmfat_chdev(const char *caller, long dnr)
2257{
2258 //
2259 FFCHECK
2260
2261 //-----------------------------------------------------------------------------------
2262 //
2263 if(jtmfat_ready!=TRUE)return 0;
2264
2265 //
2266 if(!isValidDevice(dnr))
2267 {
2268 dprintk("jtmfat_chdev: Invalid device %d\n",
2269 dnr);
2270 return 2;
2271 }
2272
2273 //-----------------------------------------------------------------------------------
2274 // Note: This function is called really often,
2275 // adding debug traces to this function
2276 //�will lead into a big flow of debug text.
2277 dprintk("%s was called by %s\n",
2278 __FUNCTION__, caller);
2279
2280 //
2281 FFCHECK
2282 // ALWAYS load info block,
2283 // because this function is not the fast access function,
2284 // this function's job is to do the update of the info block.
2285 jtmfat_loadinfoblock(dnr);
2286 //
2287 FFCHECK
2288 //
2289 dprintk("%s: leaving this function\n",
2290 __FUNCTION__);
2291
2292 //
2293 return fatsys->isJTMFS[dnr];
2294}
2295
2296// jtmfat_getinfoblock = Fast access to boot block of DNR(for FATGET/FATSET)
2297// jtmfat_chdev = Slow access to boot block
2298// Get handle to the boot block of the specified DNR
2299JTMFAT_INFOBLOCK *jtmfat_getinfoblock(int dnr)
2300{
2301 // Let's load new boot block.
2302 if( fatsys->bb[dnr]==NULL)
2303 jtmfat_LoadNewInfoBlock(dnr);
2304
2305 // Access cache entry only.
2306 // (will be NULL if called by flexFat before activation!!!!!)
2307 return fatsys->bb[dnr];
2308}
2309
2310// Same as getrootdir1, but this one
2311// tries to retrieve the rootdir twice
2312// with two other ways.
2313int _jtmfat_getrootdir(const char *caller, int dnr)
2314{
2315 int block;
2316
2317 //
2318 dprintk("%s was called by %s\n",
2319 __FUNCTION__, caller);
2320
2321 //
2322 FFCHECK
2323
2324 //
2325 EntranceGetrootdir=1;
2326
2327 //
2328 DEBUGLINE
2329
2330 //
2331 if(!isValidDevice(dnr))
2332 {
2333 //
2334 EntranceGetrootdir=0;
2335 printk("%s: Invalid device %d\n",
2336 __FUNCTION__, dnr);
2337 return 2;
2338 }
2339
2340 //
2341 block = jtmfat_getrootdir1(dnr);
2342 if(!block)
2343 {
2344 // Try retrying twice by first trying to chdev
2345 printk("%s: Boot block = zero ??\n",
2346 __FUNCTION__);
2347 }
2348
2349 //
2350 EntranceGetrootdir=0;
2351
2352 //
2353 return block;
2354}
2355
2356// Sets specified drive to "removable drive" -mode.
2357// Causes some minimal performance loss, but provides
2358// support for removable drives and first of all support
2359// for disk change.
2360void RemovableDevice(int dnr)
2361{
2362 //
2363 fatsys->bootinf[dnr].isRemovable = TRUE;
2364}
2365
2366// Returns the block # where the root directory resides.
2367int jtmfat_getrootdir1(int dnr)
2368{
2369 int i;
2370
2371 //
2372 DEBUGLINE
2373
2374 //
2375 if(!isValidDevice(dnr))
2376 {
2377 printk("jtmfat_getrootdir1: Invalid device %d\n",
2378 dnr);
2379 return -1988;
2380 }
2381
2382 //
2383 if(jtmfat_ready!=TRUE)
2384 return -1987;
2385
2386 // Change device if it is not yet the requested one
2387 if( fatsys->bootinf[dnr].isRemovable )
2388 {
2389 // For removable drive:
2390 if( (fatsys->bb[dnr]==NULL || !fatsys->bb[dnr]->data_offs || fatsys->isJTMFS[dnr]==FALSE) ||
2391 (GetSeconds() - fatsys->bootinf[dnr].t)>=2 )
2392 {
2393 // Update reload time.
2394 fatsys->bootinf[dnr].t = GetSeconds();
2395 // Let's load new boot block.
2396 jtmfat_LoadNewInfoBlock(dnr);
2397 }
2398 }
2399 else
2400 {
2401 // For non-removable drive:
2402 if(fatsys->bb[dnr]==NULL || !fatsys->bb[dnr]->data_offs || fatsys->isJTMFS[dnr]==FALSE)
2403 {
2404 // Let's load new boot block.
2405 jtmfat_LoadNewInfoBlock(dnr);
2406 }
2407 }
2408
2409 //
2410 dprintk("%s: Root directory at block %d on drive %d.\n",
2411 __FUNCTION__,
2412 fatsys->bb[dnr]->data_offs,
2413 dnr);
2414
2415 //
2416 return fatsys->bb[dnr]->data_offs;
2417}
2418
2419// Searches for a free block and returns it
2420// NEW: Optimized to remember location for last found
2421// free block, it'll continue search on the last position.
2422// It is much possible that it'll find another empty
2423// block after it, or it is atleast much more probable
2424// to find than when starting from the beginning at every
2425// try.
2426// When the function is called first time, it'll not
2427// use the findfreeblock_last_block_nr -variable,
2428// although it'll save the block number to it after
2429// it has ran through the operation.
2430//
2431// Fixed: Won't accept block #0 as a free one ever.
2432//
2433// Returns -1 on disk full.
2434//
2435int jtmfat_getfreeblock1(long dnr)
2436{
2437 int i,i2,amount;
2438
2439 // ------------------------------------
2440 DEBUGLINE
2441
2442 //
2443 if(jtmfat_ready!=TRUE)
2444 return -3;
2445
2446 //
2447 if( !isValidDevice(dnr) )
2448 {
2449 dprintk("jtmfat_getfreeblock1: Invalid device %d\n",
2450 dnr);
2451 return 0;
2452 }
2453
2454 // ------------------------------------
2455 DEBUGTRAP
2456
2457 //
2458 amount = getsize(dnr);
2459 if(amount<10)return -2;
2460
2461 //
2462 if (findfreeblock_last_block_nr!=-1
2463 &&
2464 findfreeblock_last_block_nr>0)
2465 {
2466 i = findfreeblock_last_block_nr;
2467 }
2468 else
2469 {
2470 //
2471 i = 0;
2472 }
2473
2474 //
2475 for(i2=0; i2<amount; i2++,i++)
2476 {
2477 //
2478 if(i<=0 || i>=amount)
2479 {
2480 i=1;
2481 }
2482
2483 //
2484 if( !jtmfat_getblock(dnr,i) )
2485 {
2486 findfreeblock_last_block_nr=i;
2487 return i;
2488 }
2489 }
2490
2491 //
2492 findfreeblock_last_block_nr=i;
2493
2494 // if not found, it returns a zero.
2495 return -1;
2496}
2497
2498//
2499long jtmfat_getfreeblock(long dnr)
2500{
2501 int b;
2502
2503 //
2504 DEBUGLINE
2505
2506 //
2507 if(!isValidDevice(dnr))
2508 {
2509 dprintk("jtmfat_getfreeblock: Invalid device %d\n",
2510 dnr);
2511 return 0;
2512 }
2513
2514 // ------------------------------------
2515 DEBUGTRAP
2516
2517 //
2518 b = jtmfat_getfreeblock1(dnr);
2519 return b;
2520}
2521
2522//------------------------------------------------------------
2523//
2524long jtmfat_isJTMFS(int dnr)
2525{
2526 //---------------------------------------
2527 // Couple checks
2528 if(jtmfat_ready!=TRUE)
2529 {
2530 printk("jtmfat isn't ready yet!\n");
2531 return FALSE;
2532 }
2533
2534 //
2535 if(!isValidDevice(dnr))
2536 return FALSE;
2537
2538 //---------------------------------------
2539 // Perform
2540 jtmfat_chdev(dnr);
2541
2542 //
2543 return fatsys->isJTMFS[dnr];
2544}
2545
2546// jtmfat_getblocksfree
2547// --------------------
2548// Returns the amount of blocks free
2549// Return value: below zero on error, zero on success
2550long jtmfat_getblocksfree(long dnr)
2551{
2552 static int i,i2,i3,i4,amount,n_free,n_allocated;
2553
2554 //
2555 DEBUGLINE
2556
2557 //
2558 if( !isValidDevice(dnr) )
2559 {
2560 dprintk("jtmfat_getblocksfree: Invalid device %d\n",
2561 dnr);
2562 return -1;
2563 }
2564
2565 // ------------------------------------
2566 DEBUGTRAP
2567
2568 // Get drive size
2569 amount=getsize(dnr);
2570 // Do sanity check
2571 if(amount<10)return 1;
2572
2573 // Find free block
2574 for(i=0,n_allocated=0,n_free=0; i<amount; i++)
2575 {
2576 if( jtmfat_getblock(dnr,i) )
2577 {
2578 n_allocated++;
2579 }
2580 else
2581 {
2582 n_free++;
2583 }
2584 }
2585
2586 //
2587 return n_free;
2588}
2589
2590// jtmfat_getblocksallocated
2591// -------------------------
2592// Returns the amount of blocks free
2593// Return value: below zero on error, zero on success
2594long jtmfat_getblocksallocated(long dnr)
2595{
2596 static int i,i2,i3,i4,
2597 amount,n_free,n_allocated;
2598
2599 //
2600 DEBUGLINE
2601
2602 //
2603 if(!isValidDevice(dnr))
2604 {
2605 dprintk("jtmfat_getblocksallocated: Invalid device %d\n",
2606 dnr);
2607 return -1;
2608 }
2609
2610 //
2611 jtmfat_chdev(dnr);
2612 if(!fatsys->isJTMFS[dnr])
2613 {
2614 dprintk("jtmfat_getblocksallocated: Non-JTMFS FS\n");
2615 return -1;
2616 }
2617
2618 // ------------------------------------
2619 DEBUGTRAP
2620
2621 //
2622 amount=getsize(dnr);
2623
2624 //
2625 for(i=0,n_allocated=0,n_free=0; i<amount; i++)
2626 {
2627 if( jtmfat_getblock(dnr,i) )
2628 {
2629 n_allocated++;
2630 }
2631 else
2632 {
2633 n_free++;
2634 }
2635 }
2636
2637 //
2638 return n_allocated;
2639}
2640
2641int jtmfat_deactivateFatDNR(int dnr)
2642{
2643 //
2644 if(!isValidDevice(dnr))return 1;
2645
2646 DEBUGLINE
2647
2648 //
2649 fatsys->fat[dnr]->isActive=0;
2650 return 0;
2651}
2652
2653//
2654void _jtmfatInformation(void)
2655{
2656 //
2657}
2658
2659//
2660
2661
2662
2663
2664
2665/*********************************************************************************/
2666/* FILE */
2667/*********************************************************************************/
2668/////////////////////////////////////////////////////////////////////////////////////////
2669// format.c
2670/////////////////////////////////////////////////////////////////////////////////////////
2671
2672//-----------------------------------------------------------------------------------------
2673// What it does do :
2674// - Creates an empty FAT
2675// - Reserves system area on FAT
2676// - Creates a basic root directory
2677int jtmfs_formatdrive(int device_nr)
2678{
2679 int nr_blocks,blocksize;
2680 char str[100];
2681
2682 //----------------------------------------------------
2683 if(!isValidDevice(device_nr)) return 10;
2684
2685 //----------------------------------------------------
2686 // Inform cache system first.
2687 DiskChange(device_nr);
2688
2689 //
2690 devsys_getdevicename(device_nr, str);
2691 dprintk("Formatting drive %s: ...\n",
2692 str);
2693 //
2694 nr_blocks=getsize(device_nr);
2695 blocksize=getblocksize(device_nr);
2696 //
2697 FFCHECK
2698
2699 //
2700 printk("Drive has %d blocks, each block consists of %d bytes\n",
2701 nr_blocks, blocksize);
2702
2703 //
2704 if(!nr_blocks)
2705 {
2706 //
2707 printk("Device is not suitable for a file system.\n");
2708 return 1;
2709 }
2710
2711 // Make sure we are using correct device:
2712 jtmfat_chdev(device_nr);
2713 // Do the job:
2714 jtmfat_createfat(device_nr);
2715 jtmfs_createrootdir(device_nr);
2716
2717 // Update drive contents at the end.
2718 FlushAll();
2719
2720 //
2721 dprintk("Format Complete.\n");
2722 return 0;
2723}
2724
2725
2726/*********************************************************************************/
2727/* FILE */
2728/*********************************************************************************/
2729// FILE NAME TRANSLATION FUNCTIONS FOR JTMFS
2730// (C) 2002 Jari Tuominen(jari.tuominen@kanetti.net)
2731// =================================================
2732
2733// Returns device number, -1 if no one defined.
2734int tell_fname(const char *fname, char *parsedfname)
2735{
2736 static int i,i2,i3,i4,hasdev,l;
2737 static char strdev[50];
2738
2739 l = strlen(fname);
2740 for(i=0,hasdev=0; i<l; i++)
2741 {
2742 if( fname[i]==':' )
2743 {
2744 // Copy found device to strdev
2745 for(i2=0; i2<i; i2++)
2746 strdev[i2] = fname[i2];
2747 strdev[i2]=0;
2748
2749 // Convert device string to an
2750 // interger based device identificator
2751 hasdev = devsys_getdevicenrbyname(strdev);
2752 if(hasdev==-1)hasdev=0;
2753
2754 // ----------------------------------
2755 // Get the file name
2756 // skip past the ':' character
2757 i++;
2758
2759 //
2760 goto nores;
2761 }
2762 }
2763 i=0;
2764nores:
2765
2766 // Copy the file name
2767 for(i2=i,i3=0; i2<l; i2++,i3++)
2768 parsedfname[i3] = fname[i2];
2769 parsedfname[i3]=0;
2770
2771 //
2772/* printk("tell_fname: Resolved following, devnr = %d, fname = '%s'\n",
2773 hasdev, parsedfname);*/
2774
2775 // Return possible device number
2776 return hasdev;
2777}
2778
2779/*********************************************************************************/
2780/* FILE */
2781/*********************************************************************************/
2782// ------------------------------------------------------------------
2783// flexFat.c - Flexible FAT system.
2784// (C) 2002-2005 by Jari Tuominen.
2785// ------------------------------------------------------------------
2786
2787//
2788void flexHealthCheck(void)
2789{
2790 int dnr,i;
2791 char *walk[]={
2792 "hda",
2793 "ram",
2794 "*"
2795 };
2796
2797 //
2798 for(i=0; strcmp(walk[i], "*"); i++)
2799 {
2800 dnr = devsys_getdevicenrbyname(walk[i]);
2801 if(dnr!=-1)
2802 {
2803 AnalyzeFAT(&fle->FAT[dnr]);
2804 }
2805 }
2806}
2807
2808//----------------------------------------------------------------
2809// Initialize flex fat system
2810//
2811void flexFatInit(void)
2812{
2813 int i;
2814 FLEFAT *f;
2815
2816 //
2817 fle = procmalloc(sizeof(FLEFATSYS), 0, __FUNCTION__);
2818 if(fle==NULL)
2819 panic("NULL ptr case 12");
2820
2821 // Reset main structure
2822 memset(fle,0,sizeof(FLEFATSYS));
2823
2824 //
2825 for(i=0; i<N_MAX_FATS; i++)
2826 {
2827 //
2828 f = &fle->FAT[i];
2829
2830 //
2831 f->isOK = FALSE;
2832 }
2833
2834 //
2835 flexActive = TRUE;
2836
2837 //
2838// addPitHandler(AnalyzeFATs);
2839}
2840
2841// Flush contents of FAT cache to disk
2842void flexFlushFAT(int dnr)
2843{
2844 FLEFAT *f;
2845
2846 //
2847 DEBUGINFO
2848
2849 //
2850 f = &fle->FAT[dnr];
2851 if(f->isOK)
2852 {
2853 //
2854 printk("%s: WRITING FAT DNR = %d\n",
2855 __FUNCTION__, f->dnr);
2856// waitkey();
2857 flexRWFAT(f, WRITE);
2858 }
2859}
2860
2861// Clears contents of a FAT
2862void clearFatContents(FLEFAT *f)
2863{
2864 //
2865 if( illegal(f) )
2866 panic("NULL PTR case 11");
2867
2868 //
2869 printk("f->buf clearing\n");
2870 memset(f->buf, 0, f->l_buf);
2871 printk("f->writemap clearing\n");
2872 memset(f->writemap, 0, f->l_writemap);
2873}
2874
2875// Allocate FAT data buffers for drive.
2876int flexAllocateFat(FLEFAT *f)
2877{
2878 static char str[256];
2879
2880 //
2881 if( illegal(f) )
2882 panic("NULL ptr case 10");
2883
2884 // Buffer
2885 if(f->buf==NULL)
2886 {
2887 //
2888 f->l_buf = getsize(f->dnr)*4;
2889 if(f->l_buf >= MAX_FAT_SIZE)
2890 {
2891 // We can't allocate, FAT is too big (TODO !!).
2892 return 1982;
2893 }
2894
2895 f->buf = procmalloc(f->l_buf, 0, __FUNCTION__);
2896
2897 if( illegal(f->buf) )
2898 {
2899 sprintf(str, "%s: error alloc 1 (illegal PTR: buf = 0x%x, l_buf=%d)",
2900 __FUNCTION__, f->buf, f->l_buf);
2901 panic(str);
2902 }
2903 memset(f->buf, 0, f->l_buf);
2904 printk("%s: f->buf = 0x%x\n",
2905 __FUNCTION__, f->buf);
2906 }
2907
2908 // Write map
2909 if(f->writemap==NULL)
2910 {
2911 //
2912 f->l_writemap = (getsize(f->dnr)*4/getblocksize(f->dnr));
2913 if(f->l_writemap >= MAX_FAT_SIZE)
2914 {
2915 // We can't allocate, FAT is too big (TODO !!).
2916 return 1983;
2917 }
2918
2919 f->writemap = procmalloc(f->l_writemap, 0, __FUNCTION__);
2920
2921 if( illegal(f->writemap) )
2922 panic("error alloc 2");
2923 memset(f->writemap, 0, f->l_writemap);
2924 printk("%s: f->writemap = 0x%x\n",
2925 __FUNCTION__, f->writemap);
2926 }
2927
2928 //
2929 printk("%s: Calling clearFatContents.",
2930 __FUNCTION__);
2931 clearFatContents(f);
2932}
2933
2934// Analyze all known FATs for any corruption
2935void AnalyzeFATs(void)
2936{
2937 int dnr;
2938
2939 //
2940 dnr = devsys_getdevicenrbyname("ram");
2941 AnalyzeFAT( &fle->FAT[dnr] );
2942
2943 //
2944 dnr = devsys_getdevicenrbyname("hda");
2945 AnalyzeFAT( &fle->FAT[dnr] );
2946}
2947
2948// Analyze FAT table for any errors (integrity check)
2949void AnalyzeFAT(FLEFAT *f)
2950{
2951 int i,errors,sz,conti,maxconti,maxoffs,offs,key;
2952 DWORD v;
2953 char str[50];
2954
2955 //
2956 return;
2957
2958 //-----------------------------------------------------------
2959 // Is this FAT active?
2960 if( f->isOK==FALSE )
2961 return;
2962
2963 //-----------------------------------------------------------
2964 // Get actual drive size
2965 sz = getsize(f->dnr);
2966
2967 //
2968 for(i=0,errors=0,conti=0,maxconti=0; i<sz; i++)
2969 {
2970 //
2971 v = f->buf[i];
2972 if(v<0xFFFFFF00)
2973 {
2974 //
2975 if(v >= f->max_val)
2976 {
2977 // Show upto 10 errors, then stop showing
2978 // these to speed up the process...
2979 if(errors<10)
2980 {
2981 //
2982 // printk("%c%c%c%c",
2983 // v&255, v>>8&255, v>>16&255, v>>24&255);
2984 printk("reads=%x, max. allowed=%x, location=%d/%d\n",
2985 v, f->max_val, i,sz);
2986 }
2987
2988 //
2989 errors++;
2990 if(offs==0) offs = i;
2991 conti++;
2992
2993 // Fix location with SYSTEM RESERVED value.
2994 f->buf[i] = 0xFFFFFFF7;
2995 }
2996 else
2997 {
2998 //
2999 if(conti && conti>maxconti)
3000 {
3001 maxconti = conti;
3002 maxoffs = offs;
3003 }
3004 //
3005 conti=0;
3006 }
3007 }
3008 }
3009
3010 // If any errors detected
3011 if(errors)
3012 {
3013 // Get user attention
3014 Attention();
3015 // Show user what we got
3016 devsys_getdevicename(f->dnr, str),
3017 printk("\n* FAT table for drive #%d(%s) is corrupted: table contains unaccepted values (%d errors detected). *\n",
3018 f->dnr, str, errors);
3019 printk("Largest contigous corrupted area = %d bytes.\n",
3020 maxconti*4);
3021
3022 //
3023 while(1)
3024 {
3025 //
3026 printk("Run global search(Y/N)?");
3027 key = getch();
3028 if(key=='Y')
3029 {
3030 // Search whole kernel memory for this pattern.
3031 GlobalSearch(&f->buf[maxoffs], maxconti*4);
3032
3033 // Wait until user hits key.
3034 getch();
3035 break;
3036 }
3037 if(key=='N')
3038 break;
3039
3040 //
3041 printk("\nPlease answer Y or N with caps.\n");
3042 }
3043
3044 //
3045 }
3046}
3047
3048
3049// Read whole FAT in memory at once.
3050// [or]
3051// Write changed FAT areas on drive.
3052// RW must equal to READ or WRITE.
3053void flexRWFAT(FLEFAT *f, int rw)
3054{
3055 static int i,i2,i3,i4,b,s,e;
3056 char *p;
3057
3058 //
3059 FLEXCHECK(f)
3060
3061 // Writing?
3062 if(rw==WRITE)
3063 {
3064 // Anything left to write?
3065 if(f->writeBack==0)
3066 {
3067 // Nothing to write.
3068 return;
3069 }
3070 // Flag write
3071 else f->writeBack=0;
3072 }
3073
3074 //
3075 FLEXCHECK(f)
3076
3077 //
3078 DEBUGINFO
3079 dprintk("%s: DNR=%d\n", f->dnr);
3080
3081 //
3082 FLEXCHECK(f)
3083
3084 // Determine the block we need
3085 s = f->bb->fat_offs;
3086 e = f->bb->fat_offs + (getsize(f->dnr)*4/getblocksize(f->dnr)) + 1;
3087 for(i=s,p=f->buf,i2=0; i<e; i++,p+=getblocksize(f->dnr),i2++)
3088 {
3089 //
3090 if( (p+getblocksize(f->dnr)) >= (f->buf+f->l_buf) )
3091 {
3092 //
3093 FLEXER(1100, "flexFat EXCEEDED BUFFER BOUNDER");
3094 }
3095
3096 //
3097 if(rw==READ)
3098 {
3099 //
3100 dprintk("<%s: readblock DNR=%d, BNR=%d, p=0x%x>\n",
3101 __FUNCTION__, f->dnr, i, p);
3102 //sleep(1);
3103 readblock(f->dnr, i, p);
3104 }
3105 else
3106 if(rw==WRITE)
3107 {
3108 //
3109 if( f->writemap[i2] )
3110 {
3111 //
3112 dprintk("<%s: writeblock DNR=%d, BNR=%d, p=0x%x>\n",
3113 __FUNCTION__, f->dnr, i, p);
3114 //sleep(1);
3115 f->writemap[i2]=0;
3116 writeblock(f->dnr, i, p);
3117 }
3118 }
3119 }
3120
3121 // Analyze FAT for any integrity errors
3122 AnalyzeFAT(f);
3123
3124 //
3125 FLEXCHECK(f)
3126
3127 //
3128 dprintk("\n");
3129}
3130
3131// Activate cache
3132// Return value: (the caller must check the return value upon return!!)
3133// 0 = Success.
3134// Non-zero = Error.
3135int flexActivateFat(int dnr)
3136{
3137 FLEFAT *f;
3138
3139 // Validity check
3140 if(!isValidDevice(dnr)){ return 1981; }
3141
3142 //
3143 f = &fle->FAT[dnr];
3144
3145 //
3146 if( (f->bb=jtmfat_getinfoblock(dnr))==NULL || (f->bb && strncmp(f->bb->detstr, "JTMFS", 5)) )
3147 {
3148 //
3149 printk("%s: The drive (%d) is not JTMFS formatted, won't activate FAT.\n",
3150 __FUNCTION__, dnr);
3151 return 1980;
3152 }
3153
3154 //
3155 f->status = INITIALIZED;
3156 f->dnr = dnr;
3157 f->guard = FLFGUARD;
3158 f->writeBack = 0;
3159 f->max_val = getsize(dnr);
3160 // Define amount of FAT values.
3161 f->amount = getsize(f->dnr);
3162 // Perform allocation.
3163 return flexAllocateFat(f);
3164}
3165
3166// Returns amount of FAT entries FAT [DNR] has.
3167int flexGetFatSize(int dnr)
3168{
3169 //
3170 return fle->FAT[dnr].amount;
3171}
3172
3173// ------------------------------------------------------------------
3174int flexTouchFat(int dnr, int FATbnr)
3175{
3176 int i,i2,newBlock,rv;
3177
3178 // Validity check
3179 if(!isValidDevice(dnr)){ FLEXER(7, "flexTouchFat: (7) invalid DNR") return 1; }
3180
3181 //
3182 DEBUGFUNC
3183
3184 // 1) Activate FAT if it is not yet activated
3185 if(fle->FAT[dnr].isOK==FALSE)
3186 {
3187 // Get hang of the boot block
3188 if( (fle->FAT[dnr].bb=jtmfat_getinfoblock(dnr))==NULL )
3189 {
3190 //
3191 FLEXER(8, "flexTouchFat: (8) getinfotblock returned NULL")
3192 printk("%s: Non-JTMFS drive ?\n",
3193 __FUNCTION__);
3194 sleep(1);
3195 // Can't get hold of boot block on this device!
3196 return 1;
3197 }
3198
3199 // Allocate FAT buffer if neccesary
3200 // (contains whole FAT at once).
3201 if(fle->FAT[dnr].buf==NULL)
3202 {
3203 //
3204 if( (rv=flexActivateFat(dnr)) )
3205 return rv;
3206 }
3207
3208 // Read FAT
3209 flexRWFAT(&fle->FAT[dnr], READ);
3210
3211 // OK now
3212 fle->FAT[dnr].isOK = TRUE;
3213 }
3214
3215 // Activation was successful:
3216 return 0;
3217}
3218
3219//
3220void flexSetWM(FLEFAT *f, int entry, int what)
3221{
3222 //
3223 f->writemap[entry] = what;
3224}
3225
3226//
3227void flexAffectWM(FLEFAT *f, int entry)
3228{
3229 int bs;
3230
3231 //
3232 bs = getblocksize(f->dnr);
3233 if(bs<=0)
3234 return;
3235
3236 //
3237 f->writeBack = 1;
3238 flexSetWM(f, (entry*4)/bs, 1);
3239}
3240
3241// Get block from FAT table
3242int _flexFatGetBlock(const char *caller, int dnr,int X)
3243{
3244 FLEFAT *f;
3245 int rv;
3246
3247 // 1A) DNR validity check
3248 if(!isValidDevice(dnr)){ FLEXER(6, "flexFatGetBlock: (6) invalid DNR") return 0; }
3249
3250 //
3251// dprintk("%s was called by %s\n",
3252// __FUNCTION__, caller);
3253
3254 // 1B) Parameter validity check
3255 if( X<0 || X>=getsize(dnr) ){ FLEXER(5, "flexFatGetBlock: if( X<0 || X>=getsize(dnr)") return 0; }
3256
3257 // 2) Get permission(will do writeBack flushes also)
3258 if( (rv=flexTouchFat(dnr, X)) ){ FLEXER(4, "flexTouchFat(dnr, X)") return 0; }
3259
3260 // 3) Receive entry
3261 return FastGetBlock(dnr, X);
3262}
3263
3264// Set block
3265int _FastSetBlock(char *fun, int dnr, int which, DWORD what)
3266{
3267 FLEFAT *f;
3268 char str[256];
3269
3270 //
3271 if( flexTouchFat(dnr, which) ){ FLEXER(1, "flexFatSetBlock: touch failed") return 0; }
3272
3273 // 1C Get PTR
3274 f = &fle->FAT[dnr];
3275
3276 // 3) Change entry
3277 if((what & 0xFFFFFFF0) == 0xFFFFFFF0 || what < f->max_val)
3278 {
3279 //
3280 f->buf[which] = what;
3281 }
3282 else
3283 {
3284 // Illegal value!
3285 sprintf(str, "Function %s is attempting to set illegal FAT value(%x, max=%x) on FAT table.",
3286 fun, what, f->max_val);
3287 panic(str);
3288 }
3289
3290
3291 // 4) Declare writeback need on writeback map
3292 flexAffectWM(f, which);
3293}
3294
3295// Set block
3296int FastSetBlocks(int dnr, int x1, int x2, int what)
3297{
3298 FLEFAT *f;
3299 int x,bs;
3300
3301 //
3302 if( flexTouchFat(dnr, x1) ){ FLEXER(1, "flexFatSetBlock: touch failed") return 0; }
3303
3304 // 1C Get PTR
3305 f = &fle->FAT[dnr];
3306
3307 // 3) Change entry
3308 for(x=x1; x<x2; x++)
3309 f->buf[x] = what;
3310
3311 // 4) Declare writeback need
3312 bs = getblocksize(f->dnr);
3313 if(bs<=0) return 1;
3314 for(x=(x1*4)/bs; x<(((x2*4)/bs)+1); x++)
3315 flexSetWM(f, x, 1);
3316 return 0;
3317}
3318
3319// Get block
3320int _FastGetBlock(char *fun, int dnr, int which)
3321{
3322 FLEFAT *f;
3323
3324 //
3325 if( flexTouchFat(dnr, which) ){ FLEXER(1, "flexFatSetBlock: touch failed") return 0; }
3326
3327 // 1C Get PTR
3328 f = &fle->FAT[dnr];
3329
3330 // 3) Change entry
3331 return f->buf[which];
3332}
3333
3334// Set block on FAT table
3335int _flexFatSetBlock(const char *caller, int dnr,int X,int VALUE)
3336{
3337 FLEFAT *f;
3338
3339 //
3340// dprintk("%s was called by %s\n",
3341// __FUNCTION__, caller);
3342
3343 // 1A) DNR validity check
3344 if(!isValidDevice(dnr)){ FLEXER(3, "flexFatSetBlock: invalid dnr") return 0; }
3345
3346 // 1B) Parameter validity check
3347 if( X<0 || X>=getsize(dnr) ){ FLEXER(2, "invalid requested block #") return 0; }
3348
3349 // 2) Get permission(will do writeBack flushes also)
3350 if( flexTouchFat(dnr, X) ){ FLEXER(1, "flexFatSetBlock: touch failed") return 0; }
3351
3352 //
3353 return FastSetBlock(dnr, X, VALUE);
3354}
3355
3356// This function is called upon disk changes
3357void flexDiskChange(int dnr)
3358{
3359 FLEFAT *f;
3360 char str[256];
3361
3362 // Get FAT PTR
3363 f = &fle->FAT[dnr];
3364
3365 //
3366 if(f->status!=INITIALIZED)
3367 {
3368 return;
3369 panic("flexDiskChange call on non-initialized FAT");
3370 }
3371
3372 // Eject FAT cache for this device
3373 f->isOK = 0;
3374 devsys_getdevicename(dnr, str);
3375 printk("%s: Calling clearFatContents (device=%s).\n",
3376 __FUNCTION__, str);
3377 clearFatContents(f);
3378}
3379
3380//
3381
3382
3383
3384/*********************************************************************************/
3385/* FILE */
3386/*********************************************************************************/
3387// flexCorruption.c
3388
3389//----------------------------------------------------------------
3390// FlexFAT system report
3391//
3392void jtmfatInformation(void)
3393{
3394 int dnr;
3395
3396 // Check HDA
3397 dnr = devsys_getdevicenrbyname("hda");
3398 jtmfatInformation1(&fle->FAT[dnr], "Hard Disk Drive");
3399
3400 // Check
3401 dnr = devsys_getdevicenrbyname("ram");
3402 jtmfatInformation1(&fle->FAT[dnr], "RAM Disk Drive");
3403}
3404
3405// Check FAT structure's status
3406// FALSE = corrupted
3407// TRUE = uncorrupted, or information unavailable
3408int checkFat(FLEFAT *e)
3409{
3410 // Skip inactive FATs
3411 if(e->isOK==FALSE)
3412 return TRUE;
3413
3414 // Check guard DWORD
3415 if(e->guard!=FLFGUARD)
3416 return FALSE;
3417
3418/* // Check buffer #1
3419 if( fixalCheck(e->buf, e->l_buf)==FALSE )
3420 return FALSE;
3421
3422 // Check buffer #2
3423 if( fixalCheck(e->writemap, e->l_writemap)==FALSE )
3424 return FALSE;*/
3425
3426 // OK:
3427 return TRUE;
3428}
3429
3430// FlexFAT general corruption check
3431int ffCheck(const char *fn, const char *func, int line)
3432{
3433 int dnr;
3434 static char str[256],name[256];
3435 FLEFAT *e;
3436 int i;
3437 static char *drives[]={"ram","hda","*"};
3438 static int *dnrs[100]={-1};
3439
3440 //
3441 if(flexActive!=TRUE)
3442 return 1;
3443
3444 //
3445 return 0;
3446
3447 //
3448 for(i=0; strcmp(drives[i],"*"); i++)
3449 {
3450 // Check HDA
3451 if( (dnr=dnrs[i])==-1 )
3452 dnrs[i] = dnr = devsys_getdevicenrbyname(drives[i]);
3453 if(dnr==-1)
3454 continue;
3455 e = &fle->FAT[dnr];
3456
3457 // Check one
3458// FLEXCHECK(e);
3459
3460 // Check two
3461 if(checkFat(e)==FALSE)
3462 {
3463 //
3464 devsys_getdevicename(dnr, name);
3465 sprintf(str, "error: file %s, function %s, line %d -- FAT failure on device %s",
3466 fn, func, line,
3467 name);
3468 panic(str);
3469 }
3470 }
3471
3472 //
3473 return 0;
3474}
3475
3476// Reporter function
3477void jtmfatInformation1(FLEFAT *e, const char *name)
3478{
3479 int i,i2,i3,i4;
3480
3481 // Skip inactive FATs
3482 if(e->isOK==FALSE)
3483 return;
3484
3485 // Print descriptions
3486 printk("-------------------------------------------------------------\n");
3487 printk("REPORT FOR: %s\n", name);
3488 printk("Data PTR Data length WMAP WMAP length DNR/BNR GUARD\n");
3489
3490 // Print values
3491 printk("%x %x %x %x %d/%d %x amount=%d\n",
3492 e->buf, e->l_buf, e->writemap,
3493 e->l_writemap, e->dnr,e->bnr, e->guard,
3494 e->amount);
3495
3496 // Check guard DWORD
3497 if(e->guard!=FLFGUARD)
3498 {
3499 //
3500 printk("WARNING: entry guard variable is incorrect. This most probably indicates a corrupted FAT structure.\n");
3501 printk("%x != %x\n",
3502 e->guard, FLFGUARD);
3503 }
3504
3505/* // Check buffer #1
3506 if( fixalCheck(e->buf, e->l_buf)==FALSE )
3507 {
3508 //
3509 printk("e->buf guard is invalid, this indicates a buffer corruption.\n");
3510 }
3511
3512 // Check buffer #2
3513 if( fixalCheck(e->writemap, e->l_writemap)==FALSE )
3514 {
3515 //
3516 printk("e->writemap guard is invalid, this indicates a buffer corruption.\n");
3517 }*/
3518}
3519
3520
3521
3522
3523
3524/*********************************************************************************/
3525/* FILE */
3526/*********************************************************************************/
3527// ======================================================================
3528// Enhanced directory cache database system,
3529// aka EDCDS system.
3530// (C) 2002-2005 by Jari Tuominen.
3531//
3532// This file contains only the init routine
3533// and some few functions.
3534// Other functions are located in seperate
3535// dirdb* files.
3536// ======================================================================
3537
3538//
3539void pause(const char *s)
3540{
3541 printk(s);
3542 ESCLOCK();
3543}
3544
3545// Initialise DIRDB
3546int dirdb_init(void)
3547{
3548 // --------------------------------------
3549 int i,i2,i3,i4;
3550
3551 //
3552 if(dirdb_inited)return 1;
3553 dirdb_inited = 1;
3554
3555 // --------------------------------------
3556 // Clear structure
3557 memset(&dirdb, 0, sizeof(DIRDB));
3558
3559 // Set amount of directories in cache
3560 dirdb.total = MAX_DIRS_CACHED;
3561
3562 // Set entries amount to zero
3563 dirdb.n_entries = 0;
3564
3565 // Set state to free(for concurrency handling)
3566 dirdb.state = 0;
3567
3568 // Set all directory entries free
3569 for(i=0; i<dirdb.total; i++)
3570 {
3571 // Set guard variable
3572 dirdb.dir[i].guard = DIRDB_GUARD;
3573 // Set entry free
3574 dirdb.dir[i].isfree = 1;
3575 // Allocate data for dir data buffer
3576 dirdb.dir[i].buf = malloc(MAX_BYTES_PER_DIR);
3577 dirdb.dir[i].l_buf = MAX_BYTES_PER_DIR;
3578 // Set type to directory
3579 dirdb.dir[i].type = ID_DIRECTORY;
3580 }
3581
3582 // No cache flush request at the start up.
3583 dirdb.cacheFlushRec = 0;
3584
3585 //
3586 return 0;
3587}
3588
3589
3590
3591/*********************************************************************************/
3592/* FILE */
3593/*********************************************************************************/