Skip to content

Reduce cdfs ram #715

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jan 10, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
262 changes: 107 additions & 155 deletions iop/cdvd/cdfs/src/cdfs_iop.c
Original file line number Diff line number Diff line change
Expand Up @@ -446,35 +446,6 @@ static enum PathMatch comparePath(const char *path) {
return NOT_MATCH;
}

// Check if a TOC Entry matches our extension list
static int compareTocEntry(char *filename, const char *extensions) {
static char ext_list[129];

char *token;


strncpy(ext_list, extensions, 128);
ext_list[128] = 0;

token = strtok(ext_list, " ,");
while (token != NULL) {
char *ext_point;

// if 'token' matches extension of 'filename'
// then return a match
ext_point = strrchr(filename, '.');

if (strcasecmp(ext_point, token) == 0)
return TRUE;

/* Get next token: */
token = strtok(NULL, " ,");
}

// If not match found then return FALSE
return FALSE;
}

// Find, and cache, the requested directory, for use by GetDir or (and thus open)
// provide an optional offset variable, for use when caching dirs of greater than 500 files

Expand Down Expand Up @@ -897,7 +868,7 @@ int cdfs_readSect(u32 lsn, u32 sectors, u8 *buf) {
return FALSE; // error
}

int cdfs_getDir(const char *pathname, const char *extensions, enum CDFS_getMode getMode, struct TocEntry tocEntry[], unsigned int req_entries) {
int cdfs_getDir(const char *pathname, struct TocEntry tocEntry[], unsigned int req_entries) {
int matched_entries;
int dir_entry;

Expand All @@ -916,165 +887,146 @@ int cdfs_getDir(const char *pathname, const char *extensions, enum CDFS_getMode

DPRINTF("requested directory is %u sectors\n", cacheInfoDir.sector_num);

if ((getMode == CDFS_GET_DIRS_ONLY) || (getMode == CDFS_GET_FILES_AND_DIRS)) {
// Cache the start of the requested directory
if (!cdfs_cacheDir(cacheInfoDir.pathname, CACHE_START)) {
DPRINTF("cdfs_getDir - Call of cdfs_cacheDir failed\n\n");
return -1;
}
// Cache the start of the requested directory
if (!cdfs_cacheDir(cacheInfoDir.pathname, CACHE_START)) {
DPRINTF("cdfs_getDir - Call of cdfs_cacheDir failed\n\n");
return -1;
}

tocEntryPointer = (struct DirTocEntry *)cacheInfoDir.cache;
// skip the first self-referencing entry
tocEntryPointer = (struct DirTocEntry *)((u8 *)tocEntryPointer + tocEntryPointer->length);
tocEntryPointer = (struct DirTocEntry *)cacheInfoDir.cache;
// skip the first self-referencing entry
tocEntryPointer = (struct DirTocEntry *)((u8 *)tocEntryPointer + tocEntryPointer->length);

// skip the parent entry if this is the root
if (cacheInfoDir.path_depth == 0)
tocEntryPointer = (struct DirTocEntry *)((u8 *)tocEntryPointer + tocEntryPointer->length);
// skip the parent entry if this is the root
if (cacheInfoDir.path_depth == 0)
tocEntryPointer = (struct DirTocEntry *)((u8 *)tocEntryPointer + tocEntryPointer->length);

dir_entry = 0;
dir_entry = 0;

while (1) {
DPRINTF("cdfs_getDir - inside while-loop\n\n");
while (1) {
DPRINTF("cdfs_getDir - inside while-loop\n\n");

// parse the current cache block
for (; tocEntryPointer < (struct DirTocEntry *)(cacheInfoDir.cache + (cacheInfoDir.cache_size * 2048)); tocEntryPointer = (struct DirTocEntry *)((u8 *)tocEntryPointer + tocEntryPointer->length)) {
if (tocEntryPointer->length == 0) {
// if we have a toc entry length of zero,
// then we've either reached the end of the sector, or the end of the dir
// so point to next sector (if there is one - will be checked by next condition)
// parse the current cache block
for (; tocEntryPointer < (struct DirTocEntry *)(cacheInfoDir.cache + (cacheInfoDir.cache_size * 2048)); tocEntryPointer = (struct DirTocEntry *)((u8 *)tocEntryPointer + tocEntryPointer->length)) {
if (tocEntryPointer->length == 0) {
// if we have a toc entry length of zero,
// then we've either reached the end of the sector, or the end of the dir
// so point to next sector (if there is one - will be checked by next condition)

tocEntryPointer = (struct DirTocEntry *)(cacheInfoDir.cache + (((((u8 *)tocEntryPointer - cacheInfoDir.cache) / 2048) + 1) * 2048));
}
tocEntryPointer = (struct DirTocEntry *)(cacheInfoDir.cache + (((((u8 *)tocEntryPointer - cacheInfoDir.cache) / 2048) + 1) * 2048));
}

if (tocEntryPointer >= (struct DirTocEntry *)(cacheInfoDir.cache + (cacheInfoDir.cache_size * 2048))) {
// we've reached the end of the current cache block (which may be end of entire dir
// so just break the loop
break;
}
if (tocEntryPointer >= (struct DirTocEntry *)(cacheInfoDir.cache + (cacheInfoDir.cache_size * 2048))) {
// we've reached the end of the current cache block (which may be end of entire dir
// so just break the loop
break;
}

// Check if the current entry is a dir or a file
if (tocEntryPointer->fileProperties & 0x02) {
DPRINTF("We found a dir, and we want all dirs\n\n");
copyToTocEntry(&localTocEntry, tocEntryPointer);
// Check if the current entry is a dir or a file
if (tocEntryPointer->fileProperties & 0x02) {
DPRINTF("We found a dir, and we want all dirs\n\n");
copyToTocEntry(&localTocEntry, tocEntryPointer);

if (dir_entry == 0) {
if (cacheInfoDir.path_depth != 0) {
DPRINTF("It's the first directory entry, so name it '..'\n\n");
strcpy(localTocEntry.filename, "..");
}
if (dir_entry == 0) {
if (cacheInfoDir.path_depth != 0) {
DPRINTF("It's the first directory entry, so name it '..'\n\n");
strcpy(localTocEntry.filename, "..");
}

// Copy from localTocEntry
tocEntry[matched_entries] = localTocEntry;
matched_entries++;
} else { // it must be a file
DPRINTF("We found a file, but we dont want files (at least not yet)\n\n");
}

dir_entry++;
// Copy from localTocEntry
tocEntry[matched_entries] = localTocEntry;
matched_entries++;
} else { // it must be a file
DPRINTF("We found a file, but we dont want files (at least not yet)\n\n");
}

dir_entry++;

if ((unsigned int)matched_entries >= req_entries) // if we've filled the requested buffer
return (matched_entries); // then just return
if ((unsigned int)matched_entries >= req_entries) // if we've filled the requested buffer
return (matched_entries); // then just return

} // end of the current cache block
} // end of the current cache block

// if there is more dir to load, then load next chunk, else finish
if ((cacheInfoDir.cache_offset + cacheInfoDir.cache_size) < cacheInfoDir.sector_num) {
if (!cdfs_cacheDir(cacheInfoDir.pathname, CACHE_NEXT)) {
// failed to cache next block (should return TRUE even if
// there is no more directory, as long as a CD read didnt fail
return -1;
}
} else
break;
// if there is more dir to load, then load next chunk, else finish
if ((cacheInfoDir.cache_offset + cacheInfoDir.cache_size) < cacheInfoDir.sector_num) {
if (!cdfs_cacheDir(cacheInfoDir.pathname, CACHE_NEXT)) {
// failed to cache next block (should return TRUE even if
// there is no more directory, as long as a CD read didnt fail
return -1;
}
} else
break;

tocEntryPointer = (struct DirTocEntry *)cacheInfoDir.cache;
}
tocEntryPointer = (struct DirTocEntry *)cacheInfoDir.cache;
}

// Next do files
if ((getMode == CDFS_GET_FILES_ONLY) || (getMode == CDFS_GET_FILES_AND_DIRS)) {
// Cache the start of the requested directory
if (!cdfs_cacheDir(cacheInfoDir.pathname, CACHE_START)) {
DPRINTF("cdfs_getDir - Call of cdfs_cacheDir failed\n\n");
return -1;
}

tocEntryPointer = (struct DirTocEntry *)cacheInfoDir.cache;
// Cache the start of the requested directory
if (!cdfs_cacheDir(cacheInfoDir.pathname, CACHE_START)) {
DPRINTF("cdfs_getDir - Call of cdfs_cacheDir failed\n\n");
return -1;
}

// skip the first self-referencing entry
tocEntryPointer = (struct DirTocEntry *)((u8 *)tocEntryPointer + tocEntryPointer->length);
tocEntryPointer = (struct DirTocEntry *)cacheInfoDir.cache;

// skip the parent entry if this is the root
if (cacheInfoDir.path_depth == 0)
tocEntryPointer = (struct DirTocEntry *)((u8 *)tocEntryPointer + tocEntryPointer->length);
// skip the first self-referencing entry
tocEntryPointer = (struct DirTocEntry *)((u8 *)tocEntryPointer + tocEntryPointer->length);

dir_entry = 0;
// skip the parent entry if this is the root
if (cacheInfoDir.path_depth == 0)
tocEntryPointer = (struct DirTocEntry *)((u8 *)tocEntryPointer + tocEntryPointer->length);

while (1) {
DPRINTF("cdfs_getDir - inside while-loop\n\n");
dir_entry = 0;

// parse the current cache block
for (; tocEntryPointer < (struct DirTocEntry *)(cacheInfoDir.cache + (cacheInfoDir.cache_size * 2048)); tocEntryPointer = (struct DirTocEntry *)((u8 *)tocEntryPointer + tocEntryPointer->length)) {
if (tocEntryPointer->length == 0) {
// if we have a toc entry length of zero,
// then we've either reached the end of the sector, or the end of the dir
// so point to next sector (if there is one - will be checked by next condition)
while (1) {
DPRINTF("cdfs_getDir - inside while-loop\n\n");

tocEntryPointer = (struct DirTocEntry *)(cacheInfoDir.cache + (((((u8 *)tocEntryPointer - cacheInfoDir.cache) / 2048) + 1) * 2048));
}
// parse the current cache block
for (; tocEntryPointer < (struct DirTocEntry *)(cacheInfoDir.cache + (cacheInfoDir.cache_size * 2048)); tocEntryPointer = (struct DirTocEntry *)((u8 *)tocEntryPointer + tocEntryPointer->length)) {
if (tocEntryPointer->length == 0) {
// if we have a toc entry length of zero,
// then we've either reached the end of the sector, or the end of the dir
// so point to next sector (if there is one - will be checked by next condition)

if (tocEntryPointer >= (struct DirTocEntry *)(cacheInfoDir.cache + (cacheInfoDir.cache_size * 2048))) {
// we've reached the end of the current cache block (which may be end of entire dir
// so just break the loop
break;
}
tocEntryPointer = (struct DirTocEntry *)(cacheInfoDir.cache + (((((u8 *)tocEntryPointer - cacheInfoDir.cache) / 2048) + 1) * 2048));
}

// Check if the current entry is a dir or a file
if (tocEntryPointer->fileProperties & 0x02) {
DPRINTF("We don't want files now\n\n");
} else { // it must be a file
copyToTocEntry(&localTocEntry, tocEntryPointer);

if (strlen(extensions) > 0) {
// check if the file matches the extension list
if (compareTocEntry(localTocEntry.filename, extensions)) {
DPRINTF("We found a file that matches the requested extension list\n\n");
// Copy from localTocEntry
tocEntry[matched_entries] = localTocEntry;
matched_entries++;
} else {
DPRINTF("We found a file, but it didnt match the requested extension list\n\n");
}
} else { // no extension list to match against
DPRINTF("We found a file, and there is not extension list to match against\n\n");
if (tocEntryPointer >= (struct DirTocEntry *)(cacheInfoDir.cache + (cacheInfoDir.cache_size * 2048))) {
// we've reached the end of the current cache block (which may be end of entire dir
// so just break the loop
break;
}

// Copy from localTocEntry
tocEntry[matched_entries] = localTocEntry;
matched_entries++;
}
// Check if the current entry is a dir or a file
if (tocEntryPointer->fileProperties & 0x02) {
DPRINTF("We don't want files now\n\n");
} else { // it must be a file
copyToTocEntry(&localTocEntry, tocEntryPointer);
// Copy from localTocEntry
tocEntry[matched_entries] = localTocEntry;
matched_entries++;
}

dir_entry++;
dir_entry++;

if ((unsigned int)matched_entries >= req_entries) // if we've filled the requested buffer
return (matched_entries); // then just return
if ((unsigned int)matched_entries >= req_entries) // if we've filled the requested buffer
return (matched_entries); // then just return

} // end of the current cache block
} // end of the current cache block


// if there is more dir to load, then load next chunk, else finish
if ((cacheInfoDir.cache_offset + cacheInfoDir.cache_size) < cacheInfoDir.sector_num) {
if (!cdfs_cacheDir(cacheInfoDir.pathname, CACHE_NEXT)) {
// failed to cache next block (should return TRUE even if
// there is no more directory, as long as a CD read didnt fail
return -1;
}
} else
break;
// if there is more dir to load, then load next chunk, else finish
if ((cacheInfoDir.cache_offset + cacheInfoDir.cache_size) < cacheInfoDir.sector_num) {
if (!cdfs_cacheDir(cacheInfoDir.pathname, CACHE_NEXT)) {
// failed to cache next block (should return TRUE even if
// there is no more directory, as long as a CD read didnt fail
return -1;
}
} else
break;

tocEntryPointer = (struct DirTocEntry *)cacheInfoDir.cache;
}
tocEntryPointer = (struct DirTocEntry *)cacheInfoDir.cache;
}
// reached the end of the dir, before filling up the requested entries

Expand All @@ -1083,7 +1035,7 @@ int cdfs_getDir(const char *pathname, const char *extensions, enum CDFS_getMode

// This function uses sceCdTrayReq to check if the disc in the disc drive has changed.
// Once sceCdTrayReq is called it will reset the flag inside CDVDMAN.
// Avoid using sceCdTrayReq with SCECdTrayCheck as arguemnt in other code if possible.
// Avoid using sceCdTrayReq with SCECdTrayCheck as argument in other code if possible.

int cdfs_checkDiskChanged(enum Cdvd_Changed_Index index) {
u32 res = 0;
Expand Down
9 changes: 2 additions & 7 deletions iop/cdvd/cdfs/src/cdfs_iop.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,9 @@ struct TocEntry {
u8 fileProperties;
unsigned char dateStamp[8];
char filename[128 + 1];
u8 padding[2]; // Padding to make the structure 4 byte aligned
} __attribute__((packed));

enum CDFS_getMode {
CDFS_GET_FILES_ONLY = 1,
CDFS_GET_DIRS_ONLY = 2,
CDFS_GET_FILES_AND_DIRS = 3
};

enum Cdvd_Changed_Index {
CHANGED_TOC = 0,
CHANGED_FIO = 1,
Expand All @@ -35,7 +30,7 @@ extern int cdfs_start(void);
extern int cdfs_finish(void);
extern int cdfs_findfile(const char *fname, struct TocEntry *tocEntry);
extern int cdfs_readSect(u32 lsn, u32 sectors, u8 *buf);
extern int cdfs_getDir(const char *pathname, const char *extensions, enum CDFS_getMode getMode, struct TocEntry tocEntry[], unsigned int req_entries);
extern int cdfs_getDir(const char *pathname, struct TocEntry tocEntry[], unsigned int req_entries);
extern int cdfs_checkDiskChanged(enum Cdvd_Changed_Index index);

#endif // _CDFS_H
Loading
Loading