/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- | |
Copyright (c) 2014-2015 Datalight, Inc. | |
All Rights Reserved Worldwide. | |
This program is free software; you can redistribute it and/or modify | |
it under the terms of the GNU General Public License as published by | |
the Free Software Foundation; use version 2 of the License. | |
This program is distributed in the hope that it will be useful, | |
but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty | |
of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
GNU General Public License for more details. | |
You should have received a copy of the GNU General Public License along | |
with this program; if not, write to the Free Software Foundation, Inc., | |
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | |
*/ | |
/* Businesses and individuals that for commercial or other reasons cannot | |
comply with the terms of the GPLv2 license may obtain a commercial license | |
before incorporating Reliance Edge into proprietary software for | |
distribution in any form. Visit http://www.datalight.com/reliance-edge for | |
more information. | |
*/ | |
/** @file | |
@brief Implements routines for the inline imap. | |
The inline imap is used on volumes that are small enough for the imap bitmap | |
to be entirely contained within the metaroot. | |
*/ | |
#include <redfs.h> | |
#if REDCONF_IMAP_INLINE == 1 | |
#include <redcore.h> | |
/** @brief Get the allocation bit of a block from either metaroot. | |
@param bMR The metaroot index: either 0 or 1. | |
@param ulBlock The block number to query. | |
@param pfAllocated On successful return, populated with the allocation bit | |
of the block. | |
@return A negated ::REDSTATUS code indicating the operation result. | |
@retval 0 Operation was successful. | |
@retval -RED_EINVAL @p bMR is out of range; or @p ulBlock is out of range; | |
@p pfAllocated is `NULL`; or the current volume does not | |
use the inline imap. | |
*/ | |
REDSTATUS RedImapIBlockGet( | |
uint8_t bMR, | |
uint32_t ulBlock, | |
bool *pfAllocated) | |
{ | |
REDSTATUS ret; | |
if( (!gpRedCoreVol->fImapInline) | |
|| (bMR > 1U) | |
|| (ulBlock < gpRedCoreVol->ulInodeTableStartBN) | |
|| (ulBlock >= gpRedVolume->ulBlockCount) | |
|| (pfAllocated == NULL)) | |
{ | |
REDERROR(); | |
ret = -RED_EINVAL; | |
} | |
else | |
{ | |
*pfAllocated = RedBitGet(gpRedCoreVol->aMR[bMR].abEntries, ulBlock - gpRedCoreVol->ulInodeTableStartBN); | |
ret = 0; | |
} | |
return ret; | |
} | |
#if REDCONF_READ_ONLY == 0 | |
/** @brief Set the allocation bit of a block in the working metaroot. | |
@param ulBlock The block number to allocate or free. | |
@param fAllocated Whether to allocate the block (true) or free it (false). | |
@return A negated ::REDSTATUS code indicating the operation result. | |
@retval 0 Operation was successful. | |
@retval -RED_EINVAL @p ulBlock is out of range; or the current volume does | |
not use the inline imap. | |
*/ | |
REDSTATUS RedImapIBlockSet( | |
uint32_t ulBlock, | |
bool fAllocated) | |
{ | |
REDSTATUS ret; | |
if( (!gpRedCoreVol->fImapInline) | |
|| (ulBlock < gpRedCoreVol->ulInodeTableStartBN) | |
|| (ulBlock >= gpRedVolume->ulBlockCount)) | |
{ | |
REDERROR(); | |
ret = -RED_EINVAL; | |
} | |
else | |
{ | |
uint32_t ulOffset = ulBlock - gpRedCoreVol->ulInodeTableStartBN; | |
if(RedBitGet(gpRedMR->abEntries, ulOffset) == fAllocated) | |
{ | |
/* The driver shouldn't ever set a bit in the imap to its current | |
value. This is more of a problem with the external imap, but it | |
is checked here for consistency. | |
*/ | |
CRITICAL_ERROR(); | |
ret = -RED_EFUBAR; | |
} | |
else if(fAllocated) | |
{ | |
RedBitSet(gpRedMR->abEntries, ulOffset); | |
ret = 0; | |
} | |
else | |
{ | |
RedBitClear(gpRedMR->abEntries, ulOffset); | |
ret = 0; | |
} | |
} | |
return ret; | |
} | |
#endif | |
#endif /* REDCONF_IMAP_INLINE == 1 */ | |