PS2SDK
PS2 Homebrew Libraries
Loading...
Searching...
No Matches
bitmap_fsck.c
1/*
2# _____ ___ ____ ___ ____
3# ____| | ____| | | |____|
4# | ___| |____ ___| ____| | \ PS2DEV Open Source Project.
5#-----------------------------------------------------------------------
6# Copyright 2001-2004, ps2dev - http://www.ps2dev.org
7# Licenced under Academic Free License version 2.0
8# Review ps2sdk README & LICENSE files for further details.
9*/
10
11#include <errno.h>
12#include <stdio.h>
13#include <sysclib.h>
14#include <iomanX.h>
15#include <hdd-ioctl.h>
16
17#include "libpfs.h"
18#include "bitmap_fsck.h"
19
20#define NUM_BITMAP_ENTRIES 5
21#define BITMAP_BUFFER_SIZE 256
22#define BITMAP_BUFFER_SIZE_BYTES (BITMAP_BUFFER_SIZE * 512)
23
24extern u32 pfsMetaSize;
25extern u32 pfsBlockSize;
26
27static pfs_bitmap_t *pfsBitmapData;
28static void *pfsBitmapBuffer;
29static int PfsTempBitmapFD;
30
31// 0x00004ce8
32pfs_cache_t *pfsBitmapReadPartition(pfs_mount_t *mount, u16 subpart, u32 chunk)
33{
34 int result;
35 return pfsCacheGetData(mount, subpart, chunk + (1 << mount->inode_scale) + (0x2000 >> pfsBlockSize), PFS_CACHE_FLAG_BITMAP, &result);
36}
37
38// 0x000052c0
39static int pfsBitmapTransfer(pfs_bitmap_t *bitmap, int mode)
40{
41 hddIoctl2Transfer_t xferParams;
42 int result;
43
44 xferParams.sub = 0;
45 xferParams.sector = (bitmap->index << 8);
46 xferParams.size = BITMAP_BUFFER_SIZE;
47 xferParams.mode = mode;
48 xferParams.buffer = bitmap->bitmap;
49
50 if ((result = iomanX_ioctl2(PfsTempBitmapFD, HIOCTRANSFER, &xferParams, 0, NULL, 0)) < 0) {
51 PFS_PRINTF("error: could not read/write bitmap.\n");
52 } else {
53 bitmap->isDirty = 0;
54 }
55
56 return result;
57}
58
59// 0x00005380
60pfs_bitmap_t *pfsBitmapRead(u32 index)
61{
62 unsigned int i;
63 pfs_bitmap_t *pBitmap;
64
65 for (i = 1, pBitmap = NULL; i < NUM_BITMAP_ENTRIES; i++) {
66 if (pfsBitmapData[i].index == index) {
67 pBitmap = &pfsBitmapData[i];
68 break;
69 }
70 }
71
72 if (pBitmap != NULL) {
73 if (pBitmap->nused == 0) {
74 pBitmap = (pfs_bitmap_t *)pfsCacheUnLink((pfs_cache_t *)pBitmap);
75 }
76
77 pBitmap->nused++;
78 } else {
79 pBitmap = pfsBitmapData->next;
80 if (pBitmap->isDirty != 0) {
81 if (pfsBitmapTransfer(pBitmap, PFS_IO_MODE_WRITE) < 0) {
82 return NULL;
83 }
84 }
85
86 pBitmap->index = index;
87 pBitmap->isDirty = 0;
88 pBitmap->nused = 1;
89 if (pfsBitmapTransfer(pBitmap, PFS_IO_MODE_READ) < 0) {
90 return NULL;
91 }
92 pBitmap = (pfs_bitmap_t *)pfsCacheUnLink((pfs_cache_t *)pBitmap);
93 }
94
95 return pBitmap;
96}
97
98// 0x00005484
99void pfsBitmapFree(pfs_bitmap_t *bitmap)
100{
101 if (bitmap->nused == 0) {
102 PFS_PRINTF("error: unused cache returned\n");
103 } else {
104 bitmap->nused--;
105 if (bitmap->nused == 0) {
106 pfsCacheLink((pfs_cache_t *)pfsBitmapData->prev, (pfs_cache_t *)bitmap);
107 }
108 }
109}
110
111// 0x000054f0
112u32 *pfsGetBitmapEntry(u32 index)
113{
114 pfs_bitmap_t *bitmap;
115 u32 *result;
116
117 if ((bitmap = pfsBitmapRead(index >> 20)) != NULL) {
118 pfsBitmapFree(bitmap);
119 result = &bitmap->bitmap[(index >> 5) & 0x7FFF];
120 } else {
121 result = NULL;
122 }
123
124 return result;
125}
126
127// 0x0000567c
128int pfsBitmapPartInit(u32 size)
129{
130 int i, result;
131 unsigned int bitmapCount;
132
133 bitmapCount = (size >> 20) + (0 < ((size >> 3) & 0x0001FFFF));
134
135 for (i = 1; i < NUM_BITMAP_ENTRIES; i++) {
136 pfsBitmapData[i].isDirty = 0;
137 pfsBitmapData[i].nused = 0;
138 pfsBitmapData[i].index = i - 1;
139 memset(pfsBitmapData[i].bitmap, 0, BITMAP_BUFFER_SIZE_BYTES);
140 }
141
142 if (bitmapCount >= NUM_BITMAP_ENTRIES) {
143 for (i = 1; i < NUM_BITMAP_ENTRIES; i++) {
144 if ((result = pfsBitmapTransfer(&pfsBitmapData[i], PFS_IO_MODE_WRITE)) < 0) {
145 PFS_PRINTF("error: could not initialize bitmap.\n");
146 return result;
147 }
148 }
149
150 for (i = NUM_BITMAP_ENTRIES - 1; (u32)i < bitmapCount; i++) {
151 pfsBitmapData[NUM_BITMAP_ENTRIES - 1].index = i;
152 if ((result = pfsBitmapTransfer(&pfsBitmapData[NUM_BITMAP_ENTRIES - 1], PFS_IO_MODE_WRITE)) < 0) {
153 PFS_PRINTF("error: could not initialize bitmap.\n");
154 return result;
155 }
156 }
157
158 result = 0;
159 } else {
160 result = 0;
161 }
162
163 return result;
164}
165
166// 0x000057bc
167int pfsBitmapInit(void)
168{
169 u32 *bitmap;
170 int i;
171
172#ifdef FSCK100
173 iomanX_remove("hdd0:_tmp");
174
175 if ((PfsTempBitmapFD = iomanX_open("hdd0:_tmp,,,128M,PFS", O_CREAT | O_RDWR)) < 0)
176 PFS_PRINTF("error: could not create temporary partition.\n");
177#else
178 if ((PfsTempBitmapFD = iomanX_open("hdd0:__mbr", O_RDWR)) < 0) {
179 PFS_PRINTF("error: could not open mbr partition.\n");
180 return PfsTempBitmapFD;
181 }
182#endif
183
184 if ((pfsBitmapBuffer = pfsAllocMem((NUM_BITMAP_ENTRIES - 1) * BITMAP_BUFFER_SIZE_BYTES)) == NULL || (pfsBitmapData = pfsAllocMem(NUM_BITMAP_ENTRIES * sizeof(pfs_bitmap_t))) == NULL) {
185 return -ENOMEM;
186 }
187
188 memset(pfsBitmapData, 0, NUM_BITMAP_ENTRIES * sizeof(pfs_bitmap_t));
189
190 pfsBitmapData[0].next = pfsBitmapData;
191 pfsBitmapData[0].prev = pfsBitmapData;
192
193 bitmap = pfsBitmapBuffer;
194 for (i = 1; i < NUM_BITMAP_ENTRIES; i++) {
195 pfsBitmapData[i].bitmap = bitmap;
196 bitmap = (u32 *)((u8 *)bitmap + BITMAP_BUFFER_SIZE_BYTES);
197 pfsCacheLink((pfs_cache_t *)pfsBitmapData[0].prev, (pfs_cache_t *)&pfsBitmapData[i]);
198 }
199
200 return 0;
201}
#define ENOMEM
Definition errno.h:43
#define HIOCTRANSFER
Definition hdd-ioctl.h:63