fscreate.c
2.29 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
#include <PR/bcp.h>
#include <os.h>
#include "os_bbfs.h"
#include "bbint.h"
void
__osBbFsFormatName(char fname[BB_INODE16_NAMELEN], const char* name) {
int i, j;
/* reformat name to XXXXXXXXYYY filling with 0s */
for(i = 0; name[i] && name[i] != '.' && i < BB_INODE16_NAMELEN-3; i++)
fname[i] = name[i];
for(j = i; j < BB_INODE16_NAMELEN-3; j++) fname[j] = '\0';
if (name[i] == '.') {
i++;
while(name[i] && j < BB_INODE16_NAMELEN)
fname[j++] = name[i++];
}
while(j < BB_INODE16_NAMELEN)
fname[j++] = '\0';
}
s32
osBbFCreate(const char* name, u8 type, u32 len) {
u16 i, b, prev = 0;
BbInode* in = 0;
BbFat16* fat;
s32 rv = 0, incr;
char fname[BB_INODE16_NAMELEN];
if (len&(BB_FL_BLOCK_SIZE-1)) return BBFS_ERR_INVALID;
__osBbFsFormatName(fname, name);
if (!fname[0]) return BBFS_ERR_INVALID;
if ((rv = __osBbFsGetAccess()) < 0) return rv;
fat = __osBbFat;
/* check if entry already exists and find free inode */
rv = BBFS_ERR_EXISTS;
for(i = 0; i < BB_INODE16_ENTRIES; i++) {
if (fat->inode[i].type && bcmp(fname, fat->inode[i].name, BB_INODE16_NAMELEN) == 0)
goto error;
if (fat->inode[i].type == 0 && !in)
in = fat->inode+i;
}
if (!in) {
rv = BBFS_ERR_SPACE;
goto error;
}
if (len > BB_BIG_FILE_THRESHOLD) {
/* big files go low in the fat */
b = BB_FL_BYTE_TO_BLOCK(BB_SYSTEM_AREA_SIZE); incr = 1;
} else {
/* small files at the other end */
b = __osBbFsBlocks-1; incr = -1;
}
in->block = BB_FAT_LAST;
for(i = 0; i < BB_FL_BYTE_TO_BLOCK(len+BB_FL_BLOCK_SIZE-1); i++) {
/* allocate a block */
while(b < __osBbFsBlocks && BB_FAT16_NEXT(fat,b) != BB_FAT_AVAIL)
b += incr;
if (b >= __osBbFsBlocks) goto error_undo;
BB_FAT16_NEXT(fat,b) = BB_FAT_LAST;
if (prev) BB_FAT16_NEXT(fat,prev) = b;
else in->block = b;
prev = b;
}
bcopy(fname, in->name, BB_INODE16_NAMELEN);
in->type = 1;
in->size = len;
if ((rv = __osBbFsSync(0)) == 0) {
rv = in-fat->inode;
goto out;
}
error_undo:
/* deallocate pending allocations */
b = in->block;
while(b != BB_FAT_LAST) {
u16 n = BB_FAT16_NEXT(fat,b);
BB_FAT16_NEXT(fat,b) = BB_FAT_AVAIL;
b = n;
}
in->name[0] = in->size = in->block = 0;
rv = BBFS_ERR_SPACE;
error:
out:
__osBbFsRelAccess();
return rv;
}