Changeset 782 for Whitix/branches

Show
Ignore:
Timestamp:
07/13/08 20:41:33 (5 months ago)
Author:
mwhitworth
Message:

Add to update code, add basic create and truncate functions.

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • Whitix/branches/fs/fs/ext3/inode.c

    r760 r782  
     1/*  This file is part of Whitix. 
     2 * 
     3 *  Whitix is free software; you can redistribute it and/or modify 
     4 *  it under the terms of the GNU General Public License as published by 
     5 *  the Free Software Foundation; either version 2 of the License, or 
     6 *  (at your option) any later version. 
     7 * 
     8 *  Whitix is distributed in the hope that it will be useful, 
     9 *  but WITHOUT ANY WARRANTY; without even the implied warranty of 
     10 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
     11 *  GNU General Public License for more details. 
     12 * 
     13 *  You should have received a copy of the GNU General Public License 
     14 *  along with Whitix; if not, write to the Free Software 
     15 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA 
     16 * 
     17 */ 
     18 
    119#include <console.h> 
    220#include <malloc.h> 
     
    3250        block=groupDescs[desc].iNodeTable+((vNo % sbInfo->iNodesPerGrp)/INODES_PER_BLOCK(vNode->superBlock)); 
    3351 
    34         *buffer=BlockRead(vNode->superBlock->sDevice,block); 
     52        *buffer=BlockRead(vNode->superBlock->sDevice, block); 
    3553 
    3654        if (!*buffer) 
    3755                return -EIO; 
    3856 
    39         *iNode=((struct Ext3INode*)(*buffer)->data+(vNo % INODES_PER_BLOCK(vNode->superBlock))); 
     57        *iNode=(((struct Ext3INode*)(*buffer)->data)+(vNo % INODES_PER_BLOCK(vNode->superBlock))); 
    4058 
    4159        return 0; 
     
    6179                return -ENOMEM; 
    6280        } 
     81         
     82        /* Copy EXT3-specific data first. */ 
     83        iNodeInfo->blockGroup=(vNode->id-1)/EXT3_SUPERINFO(vNode->superBlock)->iNodesPerGrp; 
    6384 
    6485        /* Copy over the blocks */ 
    6586        for (i=0; i<15; i++) 
     87        { 
    6688                iNodeInfo->blocks[i]=iNode->blocks[i]; 
     89        } 
    6790 
    6891        /* Copy the iNode times over */ 
     
    92115 
    93116        /* Force a commit to the journal, to make sure this vNode is written to disk. */ 
    94         PreemptDisable(); 
    95117        err=JournalForceCommit(EXT3_JOURNAL(vNode)); 
    96         PreemptEnable(); 
    97118 
    98119        return err; 
     
    118139        struct Buffer* buffer, struct Ext3INode* iNode) 
    119140{ 
     141        struct Ext3INodeInfo* info=EXT3_INFO(vNode); 
     142         
    120143        if (handle) 
    121144        { 
     
    128151        iNode->mTime=vNode->mTime.seconds; 
    129152        iNode->size=vNode->size; 
    130  
     153         
     154        if (vNode->mode & VFS_ATTR_DIR) 
     155                iNode->mode=0x4000; 
     156        else if (vNode->mode & VFS_ATTR_FILE) 
     157                iNode->mode=0x8000; 
     158                 
     159        iNode->linksCount=1; 
     160        iNode->blocksCount=((vNode->size+BYTES_PER_SECTOR(vNode->superBlock)-1)/BYTES_PER_SECTOR(vNode->superBlock)); 
     161         
     162        int i; 
     163        for (i=0; i<15; i++) 
     164                iNode->blocks[i]=info->blocks[i]; 
     165         
    131166        /* TODO: Complete. */ 
    132167 
     168//      KePrint("Update\n"); 
     169 
    133170        JournalDirtyMetadata(handle, buffer); 
    134171 
    135         BufferRelease(buffer); 
     172//      BufferRelease(buffer); 
    136173 
    137174        return 0; 
     
    161198        JournalStop(handle); 
    162199 
     200        return err; 
     201} 
     202 
     203static int Ext3AddEntry(struct JournalHandle* handle, char* name, int nameLength, 
     204        struct VNode* dir, struct VNode* vNode) 
     205{ 
     206        struct Buffer* buffer; 
     207        int offset=0, recLen; 
     208        struct Ext3DirEntry* entry; 
     209         
     210//      KePrint("Here\n"); 
     211         
     212        buffer=Ext3BlockRead(dir, 0); 
     213         
     214        if (!buffer) 
     215                return -EIO; 
     216         
     217        recLen=EXT3_DIR_REC_LEN(nameLength); 
     218         
     219        entry=(struct Ext3DirEntry*)buffer->data; 
     220         
     221        while (1) 
     222        { 
     223                if ((char*)entry >= BYTES_PER_SECTOR(vNode->superBlock)+buffer->data) 
     224                { 
     225                        KePrint("New block?\n"); 
     226                        cli(); hlt(); 
     227                } 
     228                 
     229                KePrint("%u %u\n", entry->iNodeNum, entry->recLen); 
     230                 
     231                if ((entry->iNodeNum == 0 && entry->recLen >= recLen) || 
     232                        (entry->recLen >= EXT3_DIR_REC_LEN(entry->nameLen) + recLen)) 
     233                { 
     234                        JournalGetWriteAccess(handle, buffer); 
     235                         
     236                        if (entry->iNodeNum) 
     237                        { 
     238                                struct Ext3DirEntry* next; 
     239                                 
     240                                next=(struct Ext3DirEntry*)((char*)entry+EXT3_DIR_REC_LEN(entry->nameLen)); 
     241                                next->recLen=entry->recLen-EXT3_DIR_REC_LEN(entry->nameLen); 
     242                                entry->recLen=EXT3_DIR_REC_LEN(entry->nameLen); 
     243                                                                 
     244                                KePrint("de: (%u %u) %u\n", entry->recLen, entry->nameLen, next->recLen); 
     245                                entry=next; 
     246                        } 
     247                         
     248                        entry->fileType=EXT3_FT_UNKNOWN; 
     249                         
     250                        if (vNode) 
     251                        { 
     252                                entry->iNodeNum=vNode->id; 
     253                                entry->fileType=Ext3SetFileType(vNode->mode); 
     254                        } 
     255                         
     256                        entry->nameLen=nameLength; 
     257                        memcpy(entry->name, name, nameLength); 
     258                         
     259                        JournalDirtyMetadata(handle, buffer); 
     260                        return 0; 
     261                } 
     262                 
     263                offset+=entry->recLen; 
     264                entry=(struct Ext3DirEntry*)(((char*)entry)+entry->recLen); 
     265        } 
     266         
     267        KePrint("Out?\n"); 
     268        cli(); hlt(); 
     269         
     270        return 0; 
     271} 
     272 
     273static int Ext3AddNonDirEntry(struct JournalHandle* handle, char* name, int nameLength, 
     274        struct VNode* dir, struct VNode* vNode) 
     275{ 
     276        int err; 
     277         
     278        err=Ext3AddEntry(handle, name, nameLength, dir, vNode); 
     279         
     280        if (!err) 
     281        { 
     282                err=Ext3DirtyVNode(vNode); 
     283        } 
     284         
     285        return err; 
     286} 
     287 
     288int Ext3Create(struct VNode** retVal,struct VNode* dir,char* name,int nameLength) 
     289{ 
     290        struct JournalHandle* handle; 
     291        struct VNode* vNode; 
     292        int err; 
     293         
     294        handle=JournalStart(EXT3_JOURNAL(dir), EXT3_DATA_TRANS + 3); 
     295         
     296        vNode=Ext3CreateINode(handle, dir /* mode */); 
     297         
     298        /* Create directory entry. */ 
     299        err=Ext3AddNonDirEntry(handle, name, nameLength, dir, vNode); 
     300         
     301        JournalStop(handle); 
     302         
     303        *retVal=vNode; 
     304         
    163305        return err; 
    164306} 
     
    201343} 
    202344 
     345#define EXT3_DIO_CREDITS (EXT3_RESERVE_TRANS_BLOCKS+32) 
     346 
    203347int Ext3BlockMap(struct VNode* vNode, DWORD block, int flags) 
    204348{ 
    205         struct Ext3INodeInfo* iNodeInfo=(struct Ext3INodeInfo*)vNode->extraInfo; 
    206349        struct Buffer* buff; 
    207  
    208         if (block < 12) 
    209         { 
    210                 if (!iNodeInfo->blocks[block]) 
    211                 { 
    212                         if (!(flags & VFS_MAP_CREATE)) 
    213                                 return -EIO; 
    214  
    215                         KePrint("Ext3: BlockMap, iNodeInfo->blocks[%d] = 0\n", block); 
    216                         cli(); hlt(); 
    217                 } 
    218  
    219                 /* The first 12 blocks in the inode structure are direct blocks */ 
    220                 return iNodeInfo->blocks[block]; 
    221         } 
    222  
    223         block-=12; 
    224         if (block < (BYTES_PER_SECTOR(vNode->superBlock)/sizeof(unsigned long))) 
    225         { 
    226                 int sector=iNodeInfo->blocks[12]; 
    227                 buff=BlockRead(vNode->superBlock->sDevice,sector); 
    228                 if (!buff) 
    229                         return -EIO; 
    230  
    231                 DWORD* data=(DWORD*)buff->data; 
    232  
    233                 return data[block]; 
    234         } 
    235  
    236         KePrint("Ext3BlockMap: block >= 256+12\n"); 
    237         cli(); hlt(); 
    238  
     350        struct JournalHandle* handle=JournalCurrHandle(); 
     351        int ret=0; 
     352         
     353        if (flags & VFS_MAP_CREATE) 
     354        { 
     355                handle=JournalStart(EXT3_JOURNAL(vNode), EXT3_RESERVE_TRANS_BLOCKS); 
     356#if 0 
     357                if (handle->numBlocks <= EXT3_RESERVE_TRANS_BLOCKS) 
     358                { 
     359                        ret=JournalExtend(handle, EXT3_DIO_CREDITS); 
     360                         
     361                        if (ret) 
     362                        { 
     363                                ret=JournalRestart(handle, EXT3_DIO_CREDITS); 
     364                        } 
     365                } 
     366#endif 
     367 
     368#if 0 
     369#endif 
     370        } 
     371         
     372        if (!ret) 
     373        { 
     374                ret=Ext3BlockMapHandle(handle, vNode, block, flags); 
     375        } 
     376         
     377        if (flags & VFS_MAP_CREATE) 
     378        { 
     379                JournalStop(handle); 
     380        } 
     381 
     382        return ret; 
     383} 
     384 
     385int Ext3Truncate(struct VNode* vNode, int size) 
     386{ 
     387        if (size > vNode->size) 
     388        { 
     389                KePrint("Ext3Truncate, %d, %d\n", size, vNode->size); 
     390        }else if (size < vNode->size) 
     391        { 
     392                return Ext3BlockTruncate(vNode, size); 
     393        } 
     394         
    239395        return 0; 
    240396} 
     
    283439                { 
    284440                        ext3Entry=(struct Ext3DirEntry*)(buff->data+offset); 
     441                         
     442//                      KePrint("%u %u, %s (%u %u)\n", file->position, file->vNode->size, ext3Entry->name, ext3Entry->nameLen, ext3Entry->recLen); 
    285443 
    286444                        if (LIKELY(ext3Entry->iNodeNum))