Ext2_int_ReadInode(disk, Node->Inode, &inode);
size = inode.i_size;
- LOG("inode.i_block[0] = 0x%x", inode.i_block[0]);
+ LOG("inode={.i_block[0]= 0x%x, .i_size=0x%x}", inode.i_block[0], inode.i_size);
// Find Entry
// Get First Block
// - Do this ourselves as it is a simple operation
Base = inode.i_block[0] * disk->BlockSize;
// Scan directory
- while(Pos -- && size > 0)
+ while(Pos -- && size > 0 && size <= inode.i_size)
{
VFS_ReadAt( disk->FD, Base+ofs, sizeof(tExt2_DirEnt), &dirent);
ofs += dirent.rec_len;
}
ofs = 0;
Base = Ext2_int_GetBlockAddr( disk, inode.i_block, block );
+ if( Base == 0 ) {
+ size = 0;
+ break;
+ }
}
}
// Check for the end of the list
- if(size <= 0) {
+ if(size <= 0 || size > inode.i_size) {
LEAVE('n');
return NULL;
}
// Read Entry
VFS_ReadAt( disk->FD, Base+ofs, sizeof(tExt2_DirEnt), &dirent );
- //LOG("dirent.inode = %i", dirent.inode);
- //LOG("dirent.rec_len = %i", dirent.rec_len);
- //LOG("dirent.name_len = %i", dirent.name_len);
+ LOG("dirent={.rec_len=%i,.inode=0x%x,.name_len=%i}",
+ dirent.rec_len, dirent.inode, dirent.name_len);
dirent.name[ dirent.name_len ] = '\0'; // Cap off string
+ if( dirent.name_len == 0 ) {
+ LEAVE('p', VFS_SKIP);
+ return VFS_SKIP;
+ }
// Ignore . and .. (these are done in the VFS)
if( (dirent.name[0] == '.' && dirent.name[1] == '\0')
if( (tmpNode = Inode_GetCache(Disk->CacheID, InodeID)) )
return tmpNode;
-
+
+ memset(&retNode, 0, sizeof(retNode));
// Set identifiers
retNode.Inode = InodeID;
// Set file length
retNode.Size = inode.i_size;
- retNode.Data = NULL;
// Set Access Permissions
retNode.UID = inode.i_uid;
}\r
\r
int was_not_referenced = (Node->ImplInt == 0);\r
- if( Inode_UncacheNode(disk->CacheID, Node->Inode) && was_not_referenced )\r
+ tVFS_ACL *acls = Node->ACLs;\r
+ if( Inode_UncacheNode(disk->CacheID, Node->Inode) )\r
{\r
- // Remove inode\r
+ if( was_not_referenced )\r
+ {\r
+ // Remove inode\r
+ }\r
+ if( acls != &gVFS_ACL_EveryoneRW ) {\r
+ free(acls);\r
+ }\r
}\r
return ;\r
}\r
typedef uint32_t tTID;
// NOTE: Since this is single-threaded (for now) mutexes can be implimented as simple locks
-typedef char tMutex;
typedef char tShortSpinlock;
typedef int64_t tTime;
extern int DivUp(int value, int divisor);
extern uint64_t DivMod64U(uint64_t Num, uint64_t Den, uint64_t *Rem);
-static inline int Mutex_Acquire(tMutex *m) {
- if(*m) Log_KernelPanic("---", "Double mutex lock");
- *m = 1;
- return 0;
-}
-static inline void Mutex_Release(tMutex *m) { *m = 0; }
-
static inline void SHORTLOCK(tShortSpinlock *Lock) {
if(*Lock) Log_KernelPanic("---", "Double short lock");
*Lock = 1;
--- /dev/null
+
+#ifndef _MUTEX_H_
+#define _MUTEX_H_
+
+typedef struct {
+ void *LockerReturnAddr;
+} tMutex;
+
+static inline int Mutex_Acquire(tMutex *m) {
+ if(m->LockerReturnAddr)
+ Log_KernelPanic("---", "Double mutex lock of %p by %p (was locked by %p)",
+ m, __builtin_return_address(0), m->LockerReturnAddr);
+ m->LockerReturnAddr = __builtin_return_address(0);;
+ return 0;
+}
+static inline void Mutex_Release(tMutex *m) { m->LockerReturnAddr = 0; }
+
+#endif
+