PS2SDK
PS2 Homebrew Libraries
Loading...
Searching...
No Matches
journal.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# PFS metadata journal related routines
11*/
12
13#include <stdio.h>
14#ifdef _IOP
15#include <sysclib.h>
16#else
17#include <string.h>
18#endif
19#include <hdd-ioctl.h>
20
21#include "libpfs.h"
22
23extern u32 pfsBlockSize;
24
26// Globals
27
28pfs_journal_t pfsJournalBuf;
29
31// Function defenitions
32
33int pfsJournalChecksum(void *header)
34{
35 u32 *ptr=(u32 *)header;
36 u32 sum=0;
37 int i;
38 for(i=2; i < 256; i++)
39 sum+=ptr[i];
40 return sum & 0xFFFF;
41}
42
43void pfsJournalWrite(pfs_mount_t *pfsMount, pfs_cache_t *clink, u32 pfsCacheNumBuffers)
44{
45 u32 i=0;
46 u32 logSector=2;
47
48#ifdef PFS_SUPPORT_BHDD
49 if (strcmp(pfsMount->blockDev->devName, "bhdd") == 0)
50 return;
51#endif
52
53 for(i=0; i <pfsCacheNumBuffers;i++)
54 {
55 if((clink[i].flags & PFS_CACHE_FLAG_DIRTY) && clink[i].pfsMount == pfsMount) {
56 if(clink[i].flags & (PFS_CACHE_FLAG_SEGD|PFS_CACHE_FLAG_SEGI))
57 clink[i].u.inode->checksum=pfsInodeCheckSum(clink[i].u.inode);
58 pfsJournalBuf.log[pfsJournalBuf.num].sector = clink[i].block << pfsBlockSize;
59 pfsJournalBuf.log[pfsJournalBuf.num].sub = clink[i].sub;
60 pfsJournalBuf.log[pfsJournalBuf.num].logSector = logSector;
61 pfsJournalBuf.num+=1;
62 }
63 logSector+=2;
64 }
65
66 if(pfsMount->blockDev->transfer(pfsMount->fd, clink->u.inode, 0,
67 (pfsMount->log.number << pfsMount->sector_scale) + 2, pfsCacheNumBuffers*2,
68 PFS_IO_MODE_WRITE)>=0)
69 pfsJournalFlush(pfsMount);
70}
71
72int pfsJournalReset(pfs_mount_t *pfsMount)
73{
74 int rv;
75
76#ifdef PFS_SUPPORT_BHDD
77 if (strcmp(pfsMount->blockDev->devName, "bhdd") == 0)
78 return 0;
79#endif
80
81 memset(&pfsJournalBuf, 0, sizeof(pfs_journal_t));
82 pfsJournalBuf.magic=PFS_JOUNRNAL_MAGIC;
83
84 pfsMount->blockDev->flushCache(pfsMount->fd);
85
86 rv = pfsMount->blockDev->transfer(pfsMount->fd, &pfsJournalBuf, 0,
87 (pfsMount->log.number << pfsMount->sector_scale), 2, PFS_IO_MODE_WRITE);
88
89 pfsMount->blockDev->flushCache(pfsMount->fd);
90 return rv;
91}
92
93int pfsJournalResetThis(pfs_block_device_t *blockDev, int fd, u32 sector)
94{
95 memset(&pfsJournalBuf, 0, sizeof(pfs_journal_t));
96 pfsJournalBuf.magic=PFS_JOUNRNAL_MAGIC;
97 return blockDev->transfer(fd, &pfsJournalBuf, 0, sector, 2, 1);
98}
99
100int pfsJournalFlush(pfs_mount_t *pfsMount)
101{// this write any thing that in are journal buffer :)
102 int rv;
103
104#ifdef PFS_SUPPORT_BHDD
105 if (strcmp(pfsMount->blockDev->devName, "bhdd") == 0)
106 return 0;
107#endif
108
109 pfsMount->blockDev->flushCache(pfsMount->fd);
110
111 pfsJournalBuf.checksum=pfsJournalChecksum(&pfsJournalBuf);
112
113 rv=pfsMount->blockDev->transfer(pfsMount->fd, &pfsJournalBuf, 0,
114 (pfsMount->log.number << pfsMount->sector_scale), 2, PFS_IO_MODE_WRITE);
115
116 pfsMount->blockDev->flushCache(pfsMount->fd);
117 return rv;
118}
119
120int pfsJournalRestore(pfs_mount_t *pfsMount)
121{
122 int rv;
123 int result;
124 pfs_cache_t *clink;
125 u32 i;
126
127#ifdef PFS_SUPPORT_BHDD
128 if (strcmp(pfsMount->blockDev->devName, "bhdd") == 0)
129 return 0;
130#endif
131
132 // Read journal buffer from disk
133 rv = pfsMount->blockDev->transfer(pfsMount->fd, &pfsJournalBuf, 0,
134 (pfsMount->log.number << pfsMount->sector_scale), 2, PFS_IO_MODE_READ);
135
136 if(rv || (pfsJournalBuf.magic != PFS_JOUNRNAL_MAGIC) ||
137 (pfsJournalBuf.checksum != (u16)pfsJournalChecksum(&pfsJournalBuf)))
138 {
139 PFS_PRINTF(PFS_DRV_NAME": Error: cannot read log/invalid log\n");
140 return pfsJournalReset(pfsMount);
141 }
142
143 if(pfsJournalBuf.num == 0)
144 {
145 return pfsJournalReset(pfsMount);
146 }
147
148 clink = pfsCacheAllocClean(&result);
149 if(!clink)
150 return result;
151
152 for(i = 0; i < pfsJournalBuf.num; i++)
153 {
154 PFS_PRINTF(PFS_DRV_NAME": Log overwrite %d:%08lx\n", pfsJournalBuf.log[i].sub, pfsJournalBuf.log[i].sector);
155
156 // Read data in from log section on disk into cache buffer
157 rv = pfsMount->blockDev->transfer(pfsMount->fd, clink->u.data, 0,
158 (pfsMount->log.number << pfsMount->sector_scale) + pfsJournalBuf.log[i].logSector, 2,
159 PFS_IO_MODE_READ);
160
161 // Write from cache buffer into destination location on disk
162 if(!rv)
163 pfsMount->blockDev->transfer(pfsMount->fd, clink->u.data, pfsJournalBuf.log[i].sub,
164 pfsJournalBuf.log[i].sector, 2, PFS_IO_MODE_WRITE);
165 }
166
167 pfsCacheFree(clink);
168 return pfsJournalReset(pfsMount);
169}