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.
10 # $Id: cache.c 911 2005-03-14 21:02:17Z oopo $
11 # PFS metadata cache manipulation routines
16 pfs_cache_t
*cacheBuf
;
20 void cacheAdd(pfs_cache_t
*clink
)
23 printf("ps2fs: Warning: NULL buffer returned\n");
28 printf("ps2fs: Error: Unused cache returned\n");
33 if(clink
->pfsMount
!=NULL
) {
36 cacheLink(cacheBuf
->prev
, clink
);
40 printf("ps2fs: Warning: Invalidated buffer is in use\n");
43 cacheLink(cacheBuf
, clink
);
46 void cacheLink(pfs_cache_t
*clink
, pfs_cache_t
*cnew
)
49 cnew
->next
=clink
->next
;
50 clink
->next
->prev
=cnew
;
54 pfs_cache_t
*cacheUnLink(pfs_cache_t
*clink
)
56 clink
->prev
->next
=clink
->next
;
57 clink
->next
->prev
=clink
->prev
;
61 pfs_cache_t
*cacheUsedAdd(pfs_cache_t
*clink
)
67 int cacheTransfer(pfs_cache_t
* clink
, int mode
)
69 pfs_mount_t
*pfsMount
=clink
->pfsMount
;
72 if(pfsMount
->lastError
== 0) { // no error
73 if((err
=pfsMount
->blockDev
->transfer(pfsMount
->fd
, clink
->u
.inode
, clink
->sub
,
74 clink
->sector
<< blockSize
, 1 << blockSize
, mode
))==0) {
75 if(mode
==IOCTL2_TMODE_READ
) {
76 if(clink
->flags
& CACHE_FLAG_SEGD
&& ((pfs_inode
*)clink
->u
.inode
)->magic
!=PFS_SEGD_MAGIC
)
78 if(clink
->flags
& CACHE_FLAG_SEGI
&& ((pfs_inode
*)clink
->u
.inode
)->magic
!=PFS_SEGI_MAGIC
)
80 if(clink
->flags
& (CACHE_FLAG_SEGD
|CACHE_FLAG_SEGI
)) {
81 if(((pfs_inode
*)clink
->u
.inode
)->checksum
!=inodeCheckSum(clink
->u
.inode
))
87 printf("ps2fs: Error: Disk error partition %ld, block %ld, err %d\n",
88 clink
->sub
, clink
->sector
, err
);
89 pfsMount
->blockDev
->setPartitionError(pfsMount
->fd
);
90 fsckStat(pfsMount
, clink
->u
.superblock
, FSCK_STAT_WRITE_ERROR
, MODE_SET_FLAG
);
91 pfsMount
->lastError
=err
;
94 clink
->flags
&=~CACHE_FLAG_DIRTY
; // clear dirty :)
95 return pfsMount
->lastError
;
98 void cacheFlushAllDirty(pfs_mount_t
*pfsMount
)
103 for(i
=1;i
<numBuffers
+1;i
++){
104 if(cacheBuf
[i
].pfsMount
== pfsMount
&&
105 cacheBuf
[i
].flags
& CACHE_FLAG_DIRTY
)
109 journalWrite(pfsMount
, cacheBuf
+1, numBuffers
);
110 for(i
=1;i
<numBuffers
+1;i
++){
111 if(cacheBuf
[i
].pfsMount
== pfsMount
&&
112 cacheBuf
[i
].flags
& CACHE_FLAG_DIRTY
)
113 cacheTransfer(&cacheBuf
[i
], 1);
115 journalReset(pfsMount
);
119 pfs_cache_t
*cacheAlloc(pfs_mount_t
*pfsMount
, u16 sub
, u32 scale
,
120 int flags
, int *result
)
122 pfs_cache_t
*allocated
;
124 if (cacheBuf
->prev
==cacheBuf
&& cacheBuf
->prev
->next
==cacheBuf
->prev
) {
125 printf("ps2fs: Error: Free buffer list is empty\n");
129 allocated
=cacheBuf
->next
;
130 if (cacheBuf
->next
==NULL
)
131 printf("ps2fs: Panic: Null pointer allocated\n");
132 if (allocated
->pfsMount
&& (allocated
->flags
& CACHE_FLAG_DIRTY
))
133 cacheFlushAllDirty(allocated
->pfsMount
);
134 allocated
->flags
= flags
& CACHE_FLAG_MASKTYPE
;
135 allocated
->pfsMount
= pfsMount
;
136 allocated
->sub
= sub
;
137 allocated
->sector
= scale
;
138 allocated
->nused
= 1;
139 return cacheUnLink(allocated
);
143 pfs_cache_t
*cacheGetData(pfs_mount_t
*pfsMount
, u16 sub
, u32 sector
,
144 int flags
, int *result
)
151 for (i
=1; i
< numBuffers
+ 1; i
++)
152 if ( cacheBuf
[i
].pfsMount
&&
153 (cacheBuf
[i
].pfsMount
==pfsMount
) &&
154 (cacheBuf
[i
].sector
== sector
))
155 if (cacheBuf
[i
].sub
==sub
){
156 cacheBuf
[i
].flags
&= CACHE_FLAG_MASKSTATUS
;
157 cacheBuf
[i
].flags
|= flags
& CACHE_FLAG_MASKTYPE
;
158 if (cacheBuf
[i
].nused
== 0)
159 cacheUnLink(&cacheBuf
[i
]);
164 clink
=cacheAlloc(pfsMount
, sub
, sector
, flags
, result
);
167 if (flags
& CACHE_FLAG_NOLOAD
)
170 if ((*result
=cacheTransfer(clink
, IOCTL2_TMODE_READ
))>=0)
173 clink
->pfsMount
=NULL
;
179 pfs_cache_t
*cacheAllocClean(int *result
)
182 return cacheAlloc(NULL
, 0, 0, 0, result
);
185 // checks if the cacheBuf list has some room
188 if (cacheBuf
->prev
!= cacheBuf
) return 0;
189 return cacheBuf
->prev
->next
== cacheBuf
->prev
;
192 int cacheInit(u32 numBuf
, u32 bufSize
)
198 printf("ps2fs: Error: Number of buffers larger than 127.\n");
202 cacheData
= allocMem(numBuf
* bufSize
);
204 if(!cacheData
|| !(cacheBuf
= allocMem((numBuf
+ 1) * sizeof(pfs_cache_t
))))
208 memset(cacheBuf
, 0, (numBuf
+ 1) * sizeof(pfs_cache_t
));
210 cacheBuf
->next
= cacheBuf
;
211 cacheBuf
->prev
= cacheBuf
;
213 for(i
= 1; i
< numBuf
+ 1; i
++)
215 cacheBuf
[i
].u
.data
= cacheData
;
216 cacheLink(cacheBuf
->prev
, &cacheBuf
[i
]);
217 cacheData
+= bufSize
;
223 void cacheMarkClean(pfs_mount_t
*pfsMount
, u32 subpart
, u32 sectorStart
, u32 sectorEnd
)
227 for(i
=1; i
< numBuffers
+1;i
++){
228 if(cacheBuf
[i
].pfsMount
==pfsMount
&& cacheBuf
[i
].sub
==subpart
) {
229 if(cacheBuf
[i
].sector
>= sectorStart
&& cacheBuf
[i
].sector
< sectorEnd
)
230 cacheBuf
[i
].flags
&=~CACHE_FLAG_DIRTY
;