From 48c3c3735e3445cb2f182a12be4b24507b4a995a Mon Sep 17 00:00:00 2001 From: John Hodge Date: Sun, 28 Mar 2010 20:25:55 +0800 Subject: [PATCH] More work on the FAT driver, more messy, but more complete - Also did some documentation changes to the tVFS_Node structure --- Kernel/include/errno.h | 10 ++++-- Kernel/include/vfs.h | 10 +++++- Modules/Filesystems/FAT/fat.c | 61 +++++++++++++++++++++++--------- Modules/Filesystems/FAT/fs_fat.h | 2 +- 4 files changed, 62 insertions(+), 21 deletions(-) diff --git a/Kernel/include/errno.h b/Kernel/include/errno.h index 8bf83d8d..0b796c05 100644 --- a/Kernel/include/errno.h +++ b/Kernel/include/errno.h @@ -1,16 +1,20 @@ /* - * AcessOS Microkernel Version + * Acess2 * errno.h */ #ifndef _ERRNO_H #define _ERRNO_H -enum eErrorNums { +enum eErrorNums +{ EOK, ENOSYS, EINVAL, ENOMEM, - EACCES + EACCES, + ENOTFOUND, + EREADONLY, + ENOTIMPL }; #endif diff --git a/Kernel/include/vfs.h b/Kernel/include/vfs.h index b75710f5..a7821048 100644 --- a/Kernel/include/vfs.h +++ b/Kernel/include/vfs.h @@ -87,11 +87,19 @@ typedef struct sVFS_Node * \} */ + /** + * \name Node State + * \brief Stores the misc information about the node + * \{ + */ int ReferenceCount; //!< Number of times the node is used Uint64 Size; //!< File Size Uint32 Flags; //!< File Flags + /** + * \} + */ /** * \name Times @@ -219,7 +227,7 @@ typedef struct sVFS_Node * \param Node Pointer to this node * \param OldName Name of the item to move/delete * \param NewName New name (or NULL if unlinking is wanted) - * \return Boolean Success + * \return Zero on Success, non-zero on error (see errno.h) */ int (*Relink)(struct sVFS_Node *Node, char *OldName, char *NewName); diff --git a/Modules/Filesystems/FAT/fat.c b/Modules/Filesystems/FAT/fat.c index 92aa431a..9a3c79e8 100644 --- a/Modules/Filesystems/FAT/fat.c +++ b/Modules/Filesystems/FAT/fat.c @@ -592,13 +592,22 @@ Uint64 FAT_Read(tVFS_Node *Node, Uint64 offset, Uint64 length, void *buffer) return length; } + #if 0 + if( FAT_int_GetAddress(Node, offset, &addr) ) + { + Log_Warning("FAT", "Offset is past end of cluster chain mark"); + LEAVE('i', 0); + return 0; + } + #endif + preSkip = offset / bpc; //Skip previous clusters for(i=preSkip;i--;) { cluster = FAT_int_GetFatValue(disk, cluster); if(cluster == -1) { - Warning("FAT_Read - Offset is past end of cluster chain mark"); + Log_Warning("FAT", "Offset is past end of cluster chain mark"); LEAVE('i', 0); return 0; } @@ -956,6 +965,11 @@ int FAT_int_WriteDirEntry(tVFS_Node *Node, int ID, fat_filetable *Entry) } #if USE_LFN +// I should probably more tightly associate the LFN cache with the node +// somehow, maybe by adding a field to tVFS_Node before locking it +// Maybe .Cache or something like that (something that is free'd by the +// Inode_UncacheNode function) + /** * \fn char *FAT_int_GetLFN(tVFS_Node *node) * \brief Return pointer to LFN cache entry @@ -1151,7 +1165,7 @@ tVFS_Node *FAT_FindDir(tVFS_Node *Node, char *name) } //Check if the files are free - if(fileinfo[i&0xF].name[0] == '\0') break; //Free and last + if(fileinfo[i&0xF].name[0] == '\0') break; // Free and last if(fileinfo[i&0xF].name[0] == '\xE5') continue; //Free @@ -1235,26 +1249,34 @@ int FAT_Relink(tVFS_Node *Node, char *OldName, char *NewName) { tVFS_Node *child; fat_filetable ft = {0}; - Uint32 cluster; - int ofs; + int ret; child = FAT_FindDir(Node, OldName); - if(!child) return 0; + if(!child) return ENOTFOUND; // Delete? if( NewName == NULL ) { child->ImplInt |= FAT_FLAG_DELETE; // Mark for deletion on close - cluster = Node->Inode & 0xFFFFFFFF; - ofs = child->ImplInt & 0xFFFF; + + // Delete from the directory ft.name[0] = '\xE9'; + FAT_int_WriteDirEntry(Node, child->ImplInt & 0xFFFF, &ft); + + // Return success + ret = EOK; } // Rename else { + Log_Warning("FAT", "Renaming no yet supported %p ('%s' => '%s')", + Node, OldName, NewName); + ret = ENOTIMPL; } - return 0; + // Close child + child->Close( child ); + return ret; } /** @@ -1266,16 +1288,23 @@ void FAT_CloseFile(tVFS_Node *Node) tFAT_VolInfo *disk = Node->ImplPtr; if(Node == NULL) return ; - if( Node->ImplInt & FAT_FLAG_DIRTY ) { - #if 0 - // Write back - FAT_int_UpdateDirEntry( - Node->Inode >> 32, Node->ImplInt & 0xFFFF, - Node - ); - #endif + // Update the node if it's dirty (don't bother if it's marked for + // deletion) + if( Node->ImplInt & FAT_FLAG_DIRTY && !(Node->ImplInt & FAT_FLAG_DELETE) ) + { + tFAT_VolInfo buf[16]; + tFAT_VolInfo *ft = &buf[ (Node->ImplInt & 0xFFFF) % 16 ]; + + FAT_int_ReadDirSector(Node, (Node->ImplInt & 0xFFFF)/16, buf); + ft->size = Node->Size; + // TODO: update adate, mtime, mdate + FAT_int_WriteDirEntry(Node, Node->ImplInt & 0xFFFF, ft); + + Node->ImplInt &= ~FAT_FLAG_DIRTY; } + // TODO: Make this more thread safe somehow, probably by moving the + // Inode_UncacheNode higher up and saving the cluster value somewhere if( Node->ReferenceCount == 1 ) { // Delete LFN Cache diff --git a/Modules/Filesystems/FAT/fs_fat.h b/Modules/Filesystems/FAT/fs_fat.h index 84eee1d9..072e2bf2 100644 --- a/Modules/Filesystems/FAT/fs_fat.h +++ b/Modules/Filesystems/FAT/fs_fat.h @@ -66,7 +66,7 @@ struct fat_filetable_s { Uint8 ctimems; //!< 10ths of a second ranging from 0-199 (2 seconds) Uint16 ctime; //!< Creation Time Uint16 cdate; //!< Creation Date - Uint16 adate; //!< Accessed Data. No Time feild though + Uint16 adate; //!< Accessed Date. No Time feild though Uint16 clusterHi; //!< High Cluster. 0 for FAT12 and FAT16 Uint16 mtime; //!< Last Modified Time Uint16 mdate; //!< Last Modified Date -- 2.20.1