vfs: check userland buffers before reading them.
[haiku.git] / src / system / boot / loader / file_systems / fat / CachedBlock.cpp
blob7eaf5b856aaf0f32926ae867c4b39ece3372eaba
1 /*
2 * Copyright 2008, Haiku, Inc.
3 * Distributed under the terms of the MIT License.
5 * Authors:
6 * François Revol <revol@free.fr>
7 */
10 #include "CachedBlock.h"
12 #include <errno.h>
13 #include <stdlib.h>
14 #include <string.h>
15 #include <unistd.h>
17 #include <util/kernel_cpp.h>
20 using namespace FATFS;
23 CachedBlock::CachedBlock(Volume &volume)
25 fVolume(volume),
26 fBlockNumber(-1LL),
27 fBlock(NULL)
32 CachedBlock::CachedBlock(Volume &volume, off_t block)
34 fVolume(volume),
35 fBlockNumber(-1LL),
36 fBlock(NULL)
38 SetTo(block);
42 CachedBlock::~CachedBlock()
44 free(fBlock);
48 uint8 *
49 CachedBlock::SetTo(off_t block)
51 status_t error = SetTo(block, READ);
52 return error == B_OK ? fBlock : NULL;
56 status_t
57 CachedBlock::SetTo(off_t blockNumber, uint32 flags)
59 if (fBlock == NULL) {
60 fBlock = (uint8*)malloc(BlockSize());
61 if (fBlock == NULL)
62 return B_NO_MEMORY;
65 if (blockNumber != fBlockNumber)
66 flags |= FORCE;
68 fBlockNumber = blockNumber;
70 status_t error = B_OK;
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;
81 } else if ((flags & CLEAR) != 0)
82 memset(fBlock, 0, BlockSize());
84 if (error != B_OK)
85 fBlockNumber = -1;
87 return error;
91 status_t
92 CachedBlock::Flush()
94 if (fBlockNumber < 0)
95 return B_BAD_VALUE;
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;
104 return B_OK;