| | 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 | |
| | 200 | return err; |
| | 201 | } |
| | 202 | |
| | 203 | static 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 | |
| | 273 | static 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 | |
| | 288 | int 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 | |
| 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 | |
| | 385 | int 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 | |