vfs: check userland buffers before reading them.
[haiku.git] / src / bin / makeudfimage / PhysicalPartitionAllocator.cpp
blob7d7c9e8aa76ea1102527bee26f8525360d2baf77
1 //----------------------------------------------------------------------
2 // This software is part of the OpenBeOS distribution and is covered
3 // by the MIT License.
4 //
5 // Copyright (c) 2003 Tyler Dauwalder, tyler@dauwalder.net
6 //----------------------------------------------------------------------
8 /*! \file PartitionAllocator.h
10 Udf physical partition allocator (implementation).
13 #include "PhysicalPartitionAllocator.h"
15 extent_address PhysicalPartitionAllocator::dummyExtent;
17 PhysicalPartitionAllocator::PhysicalPartitionAllocator(uint16 number,
18 uint32 offset,
19 Allocator &allocator)
20 : fNumber(number)
21 , fOffset(offset)
22 , fAllocator(allocator)
27 /*! \brief Allocates the next available block.
29 \param block Output parameter into which the number of the
30 allocated block (in the partition) is stored.
31 \param physicalBlock Output parameter into which the number of the
32 allocated block (on the physical volume) is
33 stored.
35 \return
36 - B_OK: Success.
37 - error code: Failure, no blocks available.
39 status_t
40 PhysicalPartitionAllocator::GetNextBlock(uint32 &block, uint32 &physicalBlock)
42 status_t error = fAllocator.GetNextBlock(physicalBlock, fOffset);
43 if (!error)
44 block = physicalBlock-fOffset;
45 return error;
48 /*! \brief Allocates the next available extent of given length.
50 \param length The desired length (in bytes) of the extent.
51 \param contiguous If false, signals that an extent of shorter length will
52 be accepted. This allows for small chunks of
53 unallocated space to be consumed, provided a
54 contiguous chunk is not needed.
55 \param extent Output parameter into which the extent as allocated
56 in the partition is stored. Note that the length
57 field of the extent may be shorter than the length
58 parameter passed to this function is \a contiguous is
59 false.
60 \param physicalExtent Output parameter into which the extent as allocated
61 on the physical volume is stored. Note that the length
62 field of the extent may be shorter than the length
63 parameter passed to this function is \a contiguous is
64 false.
66 \return
67 - B_OK: Success.
68 - error code: Failure.
70 status_t
71 PhysicalPartitionAllocator::GetNextExtent(uint32 length,
72 bool contiguous,
73 long_address &extent,
74 extent_address &physicalExtent)
76 status_t error = fAllocator.GetNextExtent(length, contiguous, physicalExtent, fOffset);
77 if (!error) {
78 extent.set_partition(PartitionNumber());
79 extent.set_block(physicalExtent.location()-fOffset);
80 extent.set_length(physicalExtent.length());
82 return error;
85 /*! \brief Allocates enough extents to add up to length bytes and stores said
86 extents in the given address lists.
88 \param length The desired length (in bytes) to be allocated.
89 \param extents Output parameter into which the extents as allocated
90 in the partition are stored.
91 \param physicalExtent Output parameter into which the extents as allocated
92 on the physical volume are stored.
94 \return
95 - B_OK: Success.
96 - error code: Failure.
98 status_t
99 PhysicalPartitionAllocator::GetNextExtents(off_t length, std::list<long_address> &extents,
100 std::list<extent_address> &physicalExtents)
102 DEBUG_INIT_ETC("PhysicalPartitionAllocator", ("length: %lld", length));
103 extents.empty();
104 physicalExtents.empty();
106 // Allocate extents until we're done or we hit an error
107 status_t error = B_OK;
108 while (error == B_OK) {
109 long_address extent;
110 extent_address physicalExtent;
111 uint32 chunkLength = length <= ULONG_MAX ? uint32(length) : ULONG_MAX;
112 error = GetNextExtent(chunkLength, false, extent, physicalExtent);
113 if (!error) {
114 extents.push_back(extent);
115 physicalExtents.push_back(physicalExtent);
116 if (physicalExtent.length() > chunkLength) {
117 // This should never happen, but just to be safe
118 PRINT(("ERROR: allocated extent length longer than requested "
119 " extent length (allocated: %ld, requested: %ld)\n",
120 physicalExtent.length(), chunkLength));
121 error = B_ERROR;
122 } else {
123 // ToDo: Might want to add some checks for 0 length allocations here
124 length -= physicalExtent.length();
125 if (length == 0) {
126 // All done
127 break;
132 RETURN(error);
135 /*! \brief Returns the length of the partition in blocks.
137 uint32
138 PhysicalPartitionAllocator::Length() const
140 uint32 length = fAllocator.Length();
141 return fOffset >= length ? 0 : length-fOffset;