1 /* 2 * Copyright 2008, Haiku, Inc. 3 * Distributed under the terms of the MIT License. 4 * 5 * Authors: 6 * François Revol <revol@free.fr> 7 */ 8 9 10 #include "CachedBlock.h" 11 12 #include <errno.h> 13 #include <stdlib.h> 14 #include <string.h> 15 #include <unistd.h> 16 17 #include <util/kernel_cpp.h> 18 19 20 using namespace FATFS; 21 22 23 CachedBlock::CachedBlock(Volume &volume) 24 : 25 fVolume(volume), 26 fBlockNumber(-1LL), 27 fBlock(NULL) 28 { 29 } 30 31 32 CachedBlock::CachedBlock(Volume &volume, off_t block) 33 : 34 fVolume(volume), 35 fBlockNumber(-1LL), 36 fBlock(NULL) 37 { 38 SetTo(block); 39 } 40 41 42 CachedBlock::~CachedBlock() 43 { 44 free(fBlock); 45 } 46 47 48 uint8 * 49 CachedBlock::SetTo(off_t block) 50 { 51 status_t error = SetTo(block, READ); 52 return error == B_OK ? fBlock : NULL; 53 } 54 55 56 status_t 57 CachedBlock::SetTo(off_t blockNumber, uint32 flags) 58 { 59 if (fBlock == NULL) { 60 fBlock = (uint8*)malloc(BlockSize()); 61 if (fBlock == NULL) 62 return B_NO_MEMORY; 63 } 64 65 if (blockNumber != fBlockNumber) 66 flags |= FORCE; 67 68 fBlockNumber = blockNumber; 69 70 status_t error = B_OK; 71 72 if ((flags & READ) != 0) { 73 if ((flags & FORCE) != 0) { 74 ssize_t bytesRead = read_pos(fVolume.Device(), 75 fBlockNumber << BlockShift(), fBlock, BlockSize()); 76 if (bytesRead < 0) 77 error = bytesRead; 78 else if (bytesRead < (ssize_t)BlockSize()) 79 error = B_ERROR; 80 } 81 } else if ((flags & CLEAR) != 0) 82 memset(fBlock, 0, BlockSize()); 83 84 if (error != B_OK) 85 fBlockNumber = -1; 86 87 return error; 88 } 89 90 91 status_t 92 CachedBlock::Flush() 93 { 94 if (fBlockNumber < 0) 95 return B_BAD_VALUE; 96 97 ssize_t written = write_pos(fVolume.Device(), fBlockNumber << BlockShift(), 98 fBlock, BlockSize()); 99 if (written < 0) 100 return errno; 101 if (written != (ssize_t)BlockSize()) 102 return B_ERROR; 103 104 return B_OK; 105 } 106