Update version numbers in preparation for new release.

This commit is contained in:
Richard Barry
2015-08-05 12:59:42 +00:00
parent b4c3d91aff
commit 99d4f2c454
1451 changed files with 31767 additions and 11220 deletions
@@ -53,8 +53,8 @@
/* If the application writer needs to place the buffer used by the CLI at a
fixed address then set configAPPLICATION_PROVIDES_cOutputBuffer to 1 in
FreeRTOSConfig.h, and provide then declare an array as follows with the
following name and size in one of the application files:
FreeRTOSConfig.h, then declare an array with the following name and size in
one of the application files:
char cOutputBuffer[ configCOMMAND_INT_MAX_OUTPUT_SIZE ];
*/
#ifndef configAPPLICATION_PROVIDES_cOutputBuffer
@@ -0,0 +1,18 @@
Reliance Edge Credits
=====================
This is a list (or partial list) of people who have made non-trivial or
noteworthy contributions to the Reliance Edge project. It is sorted by name.
Entries are formatted as below:
Real Name (githubaccount)
Short description of how Real Name contributed to Reliance Edge.
The real name may be withheld by request and the GitHub account name might be
missing if the contributor does not use GitHub.
Credits
-------
None yet! ;)
@@ -0,0 +1,340 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Lesser General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
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; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but 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.
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License.
@@ -0,0 +1,115 @@
# Reliance Edge
Reliance Edge is a small, portable, highly reliable power-fail safe file system
for resource-constrained embedded systems like microcontrollers. It is written
in C and provides a familiar POSIX-like file system API, making it easy to use
in your application; or an alternate minimalist API if your application has
simple storage needs. Reliance Edge is highly configurable and can be tuned to
the precise needs of your application.
## Documentation
The complete documentation for Reliance Edge is distributed separately. It
includes an API reference and detailed discussions of various aspects of using
Reliance Edge, including porting, building, configuring, and testing. This
complete documentation, called the _Developer's Guide_, can be obtained for free
from here:
<http://www.datalight.com/reliance-edge>
In addition this README, see [doc/release_notes.md](doc/release_notes.md) for a
list of updates to Reliance Edge and a list of known issues. There is also a
quick-start guide in the doc/ directory that describes step-by-step how to
compile and run Reliance Edge in a simulated Windows environment.
## Why Use Reliance Edge?
Reliance Edge is ideal for small embedded systems with data storage
requirements, especially if there is a chance of sudden power loss or other
system failures. Compared to "raw" disk access, using a file system like
Reliance Edge removes the burden of tracking which sectors belong to which
objects, and allows data to be updated more reliably. Compared to the FAT file
system, using Reliance Edge eliminates the possibility that file system data
will be left in an inconsistent state, corrupting the disk; Reliance Edge does
not need a fsck/CHKDSK utility. Compared to journaling file systems, Reliance
Edge has less overhead and results in less storage media wear for longer device
lifetimes.
Reliance Edge uses a unique transactional model that not only prevents file
system corruption but also allows a set of changes to be made in an atomic "all
or nothing" fashion. This is very useful for applications that make sets of
interrelated changes. By using the features of Reliance Edge, a set of changes
can be incorporated into a single atomic transaction, which is committed in its
entirety or not at all even if interrupted by power loss; this means the
application does not need code to recover from partially-finished updates.
## Hardware
The typical hardware for Reliance Edge is a 32-bit microcontroller, but other
targets are possible. In its typical configurations, Reliance Edge needs at
least 4 KB to 5 KB of RAM, 11 to 18 KB of code space (on the ROM or NOR flash),
and 500 to 700 bytes of stack.
Reliance Edge is not designed for high-end embedded systems that run complicated
operating systems like Linux or Windows Embedded Compact. Embedded systems of
that variety are better served by other file systems, like Datalight's
[Reliance Nitro](http://www.datalight.com/products/embedded-file-systems/reliance-nitro).
## Getting Reliance Edge Working
Before you can use Reliance Edge, it must be ported and configured. At a
minimum, porting includes filling-in functions so that Reliance Edge can issue
commands to your storage medium; depending on your needs, other functions may
need to be filled in as well. These functions reside in a subdirectory in the
os/ directory; see os/stub/ for a blank set of functions. Configuring includes
creating a project directory (start by copying projects/newproj) and creating
the two configuration files (redconf.h/redconf.c) using the Reliance Edge
Configuration Utility (which can be downloaded from
<http://www.datalight.com/reliance-edge>).
These topics are covered in much greater detail in the _Developer's Guide_,
linked above.
## Using Reliance Edge
Using Reliance Edge is a simple matter of including the primary Reliance Edge
application header in your application (either include/redposix.h or
include/redfse.h) and compiling and linking against Reliance Edge binaries.
The Reliance Edge driver must be initialized before it is used (via the
red\_init() or RedFseInit() functions) and then volumes can be mounted and file
and directory functions invoked. The Reliance Edge API is documented in the
_Developer's Guide_ (linked above) and also via comments in the source code.
## Licensing
Reliance Edge is an open-source project licensed under the GNU General Public
License v2 (GPLv2). 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. The commercial distribution also includes extra tests and
tools not distributed with the GPLv2 version.
See LICENSE.txt for the full license terms of this distribution of the product.
## Getting Help
If you need assistance using Reliance Edge, and you have already consulted the
_Developer's Guide_, contact <RelianceEdgeSupport@datalight.com>.
In the near future, a community forum or message board will be set up to
facilitate discussion of Reliance Edge and allow users to get help from
Datalight and from each other. In the meantime, please use the email address
given above.
## Contributing
Contributions to Reliance Edge are welcome. Our policy is that Datalight must
own the copyright of all code incorporated into Reliance Edge; if contributing a
significant amount of code, you will be asked to file a copyright assignment
agreement. See CONTRIBUTING.txt for further details and contribution
guidelines.
To report bugs, please create a GitHub issue or contact
<RelianceEdgeSupport@datalight.com>.
@@ -0,0 +1,131 @@
RELIANCE EDGE
Reliance Edge is a small, portable, highly reliable power-fail safe file
system for resource-constrained embedded systems like microcontrollers.
It is written in C and provides a familiar POSIX-like file system API,
making it easy to use in your application; or an alternate minimalist
API if your application has simple storage needs. Reliance Edge is
highly configurable and can be tuned to the precise needs of your
application.
Documentation
The complete documentation for Reliance Edge is distributed separately.
It includes an API reference and detailed discussions of various aspects
of using Reliance Edge, including porting, building, configuring, and
testing. This complete documentation, called the _Developer's Guide_,
can be obtained for free from here:
http://www.datalight.com/reliance-edge
In addition this README, see doc/release_notes.md for a list of updates
to Reliance Edge and a list of known issues. There is also a quick-start
guide in the doc/ directory that describes step-by-step how to compile
and run Reliance Edge in a simulated Windows environment.
Why Use Reliance Edge?
Reliance Edge is ideal for small embedded systems with data storage
requirements, especially if there is a chance of sudden power loss or
other system failures. Compared to "raw" disk access, using a file
system like Reliance Edge removes the burden of tracking which sectors
belong to which objects, and allows data to be updated more reliably.
Compared to the FAT file system, using Reliance Edge eliminates the
possibility that file system data will be left in an inconsistent state,
corrupting the disk; Reliance Edge does not need a fsck/CHKDSK utility.
Compared to journaling file systems, Reliance Edge has less overhead and
results in less storage media wear for longer device lifetimes.
Reliance Edge uses a unique transactional model that not only prevents
file system corruption but also allows a set of changes to be made in an
atomic "all or nothing" fashion. This is very useful for applications
that make sets of interrelated changes. By using the features of
Reliance Edge, a set of changes can be incorporated into a single atomic
transaction, which is committed in its entirety or not at all even if
interrupted by power loss; this means the application does not need code
to recover from partially-finished updates.
Hardware
The typical hardware for Reliance Edge is a 32-bit microcontroller, but
other targets are possible. In its typical configurations, Reliance Edge
needs at least 4 KB to 5 KB of RAM, 11 to 18 KB of code space (on the
ROM or NOR flash), and 500 to 700 bytes of stack.
Reliance Edge is not designed for high-end embedded systems that run
complicated operating systems like Linux or Windows Embedded Compact.
Embedded systems of that variety are better served by other file
systems, like Datalight's Reliance Nitro.
Getting Reliance Edge Working
Before you can use Reliance Edge, it must be ported and configured. At a
minimum, porting includes filling-in functions so that Reliance Edge can
issue commands to your storage medium; depending on your needs, other
functions may need to be filled in as well. These functions reside in a
subdirectory in the os/ directory; see os/stub/ for a blank set of
functions. Configuring includes creating a project directory (start by
copying projects/newproj) and creating the two configuration files
(redconf.h/redconf.c) using the Reliance Edge Configuration Utility
(which can be downloaded from http://www.datalight.com/reliance-edge).
These topics are covered in much greater detail in the _Developer's
Guide_, linked above.
Using Reliance Edge
Using Reliance Edge is a simple matter of including the primary Reliance
Edge application header in your application (either include/redposix.h
or include/redfse.h) and compiling and linking against Reliance Edge
binaries. The Reliance Edge driver must be initialized before it is used
(via the red_init() or RedFseInit() functions) and then volumes can be
mounted and file and directory functions invoked. The Reliance Edge API
is documented in the _Developer's Guide_ (linked above) and also via
comments in the source code.
Licensing
Reliance Edge is an open-source project licensed under the GNU General
Public License v2 (GPLv2). 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. The
commercial distribution also includes extra tests and tools not
distributed with the GPLv2 version.
See LICENSE.txt for the full license terms of this distribution of the
product.
Getting Help
If you need assistance using Reliance Edge, and you have already
consulted the _Developer's Guide_, contact
RelianceEdgeSupport@datalight.com.
In the near future, a community forum or message board will be set up to
facilitate discussion of Reliance Edge and allow users to get help from
Datalight and from each other. In the meantime, please use the email
address given above.
Contributing
Contributions to Reliance Edge are welcome. Our policy is that Datalight
must own the copyright of all code incorporated into Reliance Edge; if
contributing a significant amount of code, you will be asked to file a
copyright assignment agreement. See CONTRIBUTING.txt for further details
and contribution guidelines.
To report bugs, please create a GitHub issue or contact
RelianceEdgeSupport@datalight.com.
@@ -0,0 +1,164 @@
/* ----> 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 block device I/O using logical blocks as the units.
The OS block device implementations operate on sectors. The core does I/O
in terms of logical blocks: this module translates from logical blocks to
sectors.
*/
#include <redfs.h>
#include <redcore.h>
/** @brief Read a range of logical blocks.
@param bVolNum The volume whose block device is being read from.
@param ulBlockStart The first block to read.
@param ulBlockCount The number of blocks to read.
@param pBuffer The buffer to populate with the data read.
@return A negated ::REDSTATUS code indicating the operation result.
@retval 0 Operation was successful.
@retval -RED_EIO A disk I/O error occurred.
@retval -RED_EINVAL Invalid parameters.
*/
REDSTATUS RedIoRead(
uint8_t bVolNum,
uint32_t ulBlockStart,
uint32_t ulBlockCount,
void *pBuffer)
{
REDSTATUS ret;
if( (bVolNum >= REDCONF_VOLUME_COUNT)
|| (ulBlockStart >= gaRedVolume[bVolNum].ulBlockCount)
|| ((gaRedVolume[bVolNum].ulBlockCount - ulBlockStart) < ulBlockCount)
|| (ulBlockCount == 0U)
|| (pBuffer == NULL))
{
REDERROR();
ret = -RED_EINVAL;
}
else
{
uint8_t bSectorShift = gaRedVolume[bVolNum].bBlockSectorShift;
uint64_t ullSectorStart = (uint64_t)ulBlockStart << bSectorShift;
uint32_t ulSectorCount = ulBlockCount << bSectorShift;
REDASSERT(bSectorShift < 32U);
REDASSERT((ulSectorCount >> bSectorShift) == ulBlockCount);
ret = RedOsBDevRead(bVolNum, ullSectorStart, ulSectorCount, pBuffer);
}
CRITICAL_ASSERT(ret == 0);
return ret;
}
#if REDCONF_READ_ONLY == 0
/** @brief Write a range of logical blocks.
@param bVolNum The volume whose block device is being written to.
@param ulBlockStart The first block to write.
@param ulBlockCount The number of blocks to write.
@param pBuffer The buffer containing the data to write.
@return A negated ::REDSTATUS code indicating the operation result.
@retval 0 Operation was successful.
@retval -RED_EIO A disk I/O error occurred.
@retval -RED_EINVAL Invalid parameters.
*/
REDSTATUS RedIoWrite(
uint8_t bVolNum,
uint32_t ulBlockStart,
uint32_t ulBlockCount,
const void *pBuffer)
{
REDSTATUS ret;
if( (bVolNum >= REDCONF_VOLUME_COUNT)
|| (ulBlockStart >= gaRedVolume[bVolNum].ulBlockCount)
|| ((gaRedVolume[bVolNum].ulBlockCount - ulBlockStart) < ulBlockCount)
|| (ulBlockCount == 0U)
|| (pBuffer == NULL))
{
REDERROR();
ret = -RED_EINVAL;
}
else
{
uint8_t bSectorShift = gaRedVolume[bVolNum].bBlockSectorShift;
uint64_t ullSectorStart = (uint64_t)ulBlockStart << bSectorShift;
uint32_t ulSectorCount = ulBlockCount << bSectorShift;
REDASSERT(bSectorShift < 32U);
REDASSERT((ulSectorCount >> bSectorShift) == ulBlockCount);
ret = RedOsBDevWrite(bVolNum, ullSectorStart, ulSectorCount, pBuffer);
}
CRITICAL_ASSERT(ret == 0);
return ret;
}
/** @brief Flush any caches beneath the file system.
@param bVolNum The volume number of the volume whose block device is being
flushed.
@return A negated ::REDSTATUS code indicating the operation result.
@retval 0 Operation was successful.
@retval -RED_EINVAL @p bVolNum is an invalid volume number.
@retval -RED_EIO A disk I/O error occurred.
*/
REDSTATUS RedIoFlush(
uint8_t bVolNum)
{
REDSTATUS ret;
if(bVolNum >= REDCONF_VOLUME_COUNT)
{
REDERROR();
ret = -RED_EINVAL;
}
else
{
ret = RedOsBDevFlush(bVolNum);
}
CRITICAL_ASSERT(ret == 0);
return ret;
}
#endif /* REDCONF_READ_ONLY == 0 */
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,235 @@
/* ----> 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 the Reliance Edge file system formatter.
*/
#include <redfs.h>
#include <redcoreapi.h>
#include <redcore.h>
#if FORMAT_SUPPORTED
/** @brief Format a file system volume.
@return A negated ::REDSTATUS code indicating the operation result.
@retval 0 Operation was successful.
@retval -RED_EBUSY Volume is mounted.
@retval -RED_EIO A disk I/O error occurred.
*/
REDSTATUS RedVolFormat(void)
{
REDSTATUS ret;
if(gpRedVolume->fMounted)
{
ret = -RED_EBUSY;
}
else
{
ret = RedOsBDevOpen(gbRedVolNum, BDEV_O_RDWR);
}
if(ret == 0)
{
MASTERBLOCK *pMB;
REDSTATUS ret2;
/* Overwrite the master block with zeroes, so that if formatting is
interrupted, the volume will not be mountable.
*/
ret = RedBufferGet(BLOCK_NUM_MASTER, BFLAG_NEW | BFLAG_DIRTY, CAST_VOID_PTR_PTR(&pMB));
if(ret == 0)
{
ret = RedBufferFlush(BLOCK_NUM_MASTER, 1U);
RedBufferDiscard(pMB);
}
if(ret == 0)
{
ret = RedIoFlush(gbRedVolNum);
}
#if REDCONF_IMAP_EXTERNAL == 1
if((ret == 0) && !gpRedCoreVol->fImapInline)
{
uint32_t ulImapBlock;
uint32_t ulImapBlockLimit = gpRedCoreVol->ulImapStartBN + (gpRedCoreVol->ulImapNodeCount * 2U);
uint16_t uImapFlags = (uint16_t)((uint32_t)BFLAG_META_IMAP | BFLAG_NEW | BFLAG_DIRTY);
/* Technically it is only necessary to create one copy of each imap
node (the copy the metaroot points at), but creating them both
avoids headaches during disk image analysis from stale imaps
left over from previous formats.
*/
for(ulImapBlock = gpRedCoreVol->ulImapStartBN; ulImapBlock < ulImapBlockLimit; ulImapBlock++)
{
IMAPNODE *pImap;
ret = RedBufferGet(ulImapBlock, uImapFlags, CAST_VOID_PTR_PTR(&pImap));
if(ret != 0)
{
break;
}
RedBufferPut(pImap);
}
}
#endif
/* Write the first metaroot.
*/
if(ret == 0)
{
RedMemSet(gpRedMR, 0U, sizeof(*gpRedMR));
gpRedMR->ulFreeBlocks = gpRedVolume->ulBlocksAllocable;
#if REDCONF_API_POSIX == 1
gpRedMR->ulFreeInodes = gpRedVolConf->ulInodeCount;
#endif
gpRedMR->ulAllocNextBlock = gpRedCoreVol->ulFirstAllocableBN;
/* The branched flag is typically set automatically when bits in
the imap change. It is set here explicitly because the imap has
only been initialized, not changed.
*/
gpRedCoreVol->fBranched = true;
ret = RedVolTransact();
}
#if REDCONF_API_POSIX == 1
/* Create the root directory.
*/
if(ret == 0)
{
CINODE rootdir;
rootdir.ulInode = INODE_ROOTDIR;
ret = RedInodeCreate(&rootdir, INODE_INVALID, RED_S_IFDIR);
if(ret == 0)
{
RedInodePut(&rootdir, 0U);
}
}
#endif
#if REDCONF_API_FSE == 1
/* The FSE API does not support creating or deletes files, so all the
inodes are created during setup.
*/
if(ret == 0)
{
uint32_t ulInodeIdx;
for(ulInodeIdx = 0U; ulInodeIdx < gpRedVolConf->ulInodeCount; ulInodeIdx++)
{
CINODE ino;
ino.ulInode = INODE_FIRST_FREE + ulInodeIdx;
ret = RedInodeCreate(&ino, INODE_INVALID, RED_S_IFREG);
if(ret == 0)
{
RedInodePut(&ino, 0U);
}
}
}
#endif
/* Write the second metaroot.
*/
if(ret == 0)
{
ret = RedVolTransact();
}
/* Populate and write out the master block.
*/
if(ret == 0)
{
ret = RedBufferGet(BLOCK_NUM_MASTER, (uint16_t)((uint32_t)BFLAG_META_MASTER | BFLAG_NEW | BFLAG_DIRTY), CAST_VOID_PTR_PTR(&pMB));
}
if(ret == 0)
{
pMB->ulVersion = RED_DISK_LAYOUT_VERSION;
RedStrNCpy(pMB->acBuildNum, RED_BUILD_NUMBER, sizeof(pMB->acBuildNum));
pMB->ulFormatTime = RedOsClockGetTime();
pMB->ulInodeCount = gpRedVolConf->ulInodeCount;
pMB->ulBlockCount = gpRedVolume->ulBlockCount;
pMB->uMaxNameLen = REDCONF_NAME_MAX;
pMB->uDirectPointers = REDCONF_DIRECT_POINTERS;
pMB->uIndirectPointers = REDCONF_INDIRECT_POINTERS;
pMB->bBlockSizeP2 = BLOCK_SIZE_P2;
#if REDCONF_API_POSIX == 1
pMB->bFlags |= MBFLAG_API_POSIX;
#endif
#if REDCONF_INODE_TIMESTAMPS == 1
pMB->bFlags |= MBFLAG_INODE_TIMESTAMPS;
#endif
#if REDCONF_INODE_BLOCKS == 1
pMB->bFlags |= MBFLAG_INODE_BLOCKS;
#endif
#if (REDCONF_API_POSIX == 1) && (REDCONF_API_POSIX_LINK == 1)
pMB->bFlags |= MBFLAG_INODE_NLINK;
#endif
ret = RedBufferFlush(BLOCK_NUM_MASTER, 1U);
RedBufferPut(pMB);
}
if(ret == 0)
{
ret = RedIoFlush(gbRedVolNum);
}
ret2 = RedOsBDevClose(gbRedVolNum);
if(ret == 0)
{
ret = ret2;
}
}
/* Discard the buffers so a subsequent format will not run into blocks it
does not expect.
*/
if(ret == 0)
{
ret = RedBufferDiscardRange(0U, gpRedVolume->ulBlockCount);
}
return ret;
}
#endif /* FORMAT_SUPPORTED */
@@ -0,0 +1,348 @@
/* ----> 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 allocation routines.
This module implements routines for working with the imap, a bitmap which
tracks which blocks are allocated or free. Some of the functionality is
delegated to imapinline.c and imapextern.c.
*/
#include <redfs.h>
#include <redcore.h>
/** @brief Get the allocation bit of a block from either metaroot.
Will pass the call down either to the inline imap or to the external imap
implementation, whichever is appropriate for the current volume.
@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;
or @p pfAllocated is `NULL`.
@retval -RED_EIO A disk I/O error occurred.
*/
REDSTATUS RedImapBlockGet(
uint8_t bMR,
uint32_t ulBlock,
bool *pfAllocated)
{
REDSTATUS ret;
if( (bMR > 1U)
|| (ulBlock < gpRedCoreVol->ulInodeTableStartBN)
|| (ulBlock >= gpRedVolume->ulBlockCount)
|| (pfAllocated == NULL))
{
REDERROR();
ret = -RED_EINVAL;
}
else
{
#if (REDCONF_IMAP_INLINE == 1) && (REDCONF_IMAP_EXTERNAL == 1)
if(gpRedCoreVol->fImapInline)
{
ret = RedImapIBlockGet(bMR, ulBlock, pfAllocated);
}
else
{
ret = RedImapEBlockGet(bMR, ulBlock, pfAllocated);
}
#elif REDCONF_IMAP_INLINE == 1
ret = RedImapIBlockGet(bMR, ulBlock, pfAllocated);
#else
ret = RedImapEBlockGet(bMR, ulBlock, pfAllocated);
#endif
}
return ret;
}
#if REDCONF_READ_ONLY == 0
/** @brief Set the allocation bit of a block in the working metaroot.
Will pass the call down either to the inline imap or to the external imap
implementation, whichever is appropriate for the current volume.
@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 @p ulBlock is allocable
and @p fAllocated is 1.
@retval -RED_EIO A disk I/O error occurred.
*/
REDSTATUS RedImapBlockSet(
uint32_t ulBlock,
bool fAllocated)
{
REDSTATUS ret;
if( (ulBlock < gpRedCoreVol->ulInodeTableStartBN)
|| (ulBlock >= gpRedVolume->ulBlockCount))
{
REDERROR();
ret = -RED_EINVAL;
}
else if( (ulBlock >= gpRedCoreVol->ulFirstAllocableBN)
&& ( (fAllocated && (gpRedMR->ulFreeBlocks == 0U))
|| ((!fAllocated) && (gpRedMR->ulFreeBlocks >= gpRedVolume->ulBlocksAllocable))))
{
/* Attempting either to free more blocks than are allocable, or
allocate a block when there are none available. This could indicate
metadata corruption.
*/
CRITICAL_ERROR();
ret = -RED_EFUBAR;
}
else
{
#if (REDCONF_IMAP_INLINE == 1) && (REDCONF_IMAP_EXTERNAL == 1)
if(gpRedCoreVol->fImapInline)
{
ret = RedImapIBlockSet(ulBlock, fAllocated);
}
else
{
ret = RedImapEBlockSet(ulBlock, fAllocated);
}
#elif REDCONF_IMAP_INLINE == 1
ret = RedImapIBlockSet(ulBlock, fAllocated);
#else
ret = RedImapEBlockSet(ulBlock, fAllocated);
#endif
/* Any change to the allocation state of a block indicates that the
volume is now branched.
*/
gpRedCoreVol->fBranched = true;
}
/* If a block was marked as no longer in use, discard it from the buffers.
*/
if((ret == 0) && (!fAllocated))
{
ret = RedBufferDiscardRange(ulBlock, 1U);
CRITICAL_ASSERT(ret == 0);
}
/* Adjust the free/almost free block count if the block was allocable.
*/
if((ret == 0) && (ulBlock >= gpRedCoreVol->ulFirstAllocableBN))
{
if(fAllocated)
{
gpRedMR->ulFreeBlocks--;
}
else
{
bool fWasAllocated;
/* Whether the block became free or almost free depends on its
previous allocation state. If it was used, then it is now
almost free. Otherwise, it was new and is now free.
*/
ret = RedImapBlockGet(1U - gpRedCoreVol->bCurMR, ulBlock, &fWasAllocated);
CRITICAL_ASSERT(ret == 0);
if(ret == 0)
{
if(fWasAllocated)
{
gpRedCoreVol->ulAlmostFreeBlocks++;
}
else
{
gpRedMR->ulFreeBlocks++;
}
}
}
}
return ret;
}
/** @brief Allocate one block.
@param pulBlock On successful return, populated with the allocated block
number.
@return A negated ::REDSTATUS code indicating the operation result.
@retval 0 Operation was successful.
@retval -RED_EINVAL @p pulBlock is `NULL`.
@retval -RED_EIO A disk I/O error occurred.
@retval -RED_ENOSPC Insufficient free space to perform the allocation.
*/
REDSTATUS RedImapAllocBlock(
uint32_t *pulBlock)
{
REDSTATUS ret;
if(pulBlock == NULL)
{
REDERROR();
ret = -RED_EINVAL;
}
else if(gpRedMR->ulFreeBlocks == 0U)
{
ret = -RED_ENOSPC;
}
else
{
uint32_t ulStopBlock = gpRedMR->ulAllocNextBlock;
bool fAllocated = false;
do
{
ALLOCSTATE state;
ret = RedImapBlockState(gpRedMR->ulAllocNextBlock, &state);
CRITICAL_ASSERT(ret == 0);
if(ret == 0)
{
if(state == ALLOCSTATE_FREE)
{
ret = RedImapBlockSet(gpRedMR->ulAllocNextBlock, true);
CRITICAL_ASSERT(ret == 0);
*pulBlock = gpRedMR->ulAllocNextBlock;
fAllocated = true;
}
/* Increment the next block number, wrapping it when the end of
the volume is reached.
*/
gpRedMR->ulAllocNextBlock++;
if(gpRedMR->ulAllocNextBlock == gpRedVolume->ulBlockCount)
{
gpRedMR->ulAllocNextBlock = gpRedCoreVol->ulFirstAllocableBN;
}
}
}
while((ret == 0) && !fAllocated && (gpRedMR->ulAllocNextBlock != ulStopBlock));
if((ret == 0) && !fAllocated)
{
/* The free block count was already determined to be non-zero, no
error occurred while looking for free blocks, but no free blocks
were found. This indicates metadata corruption.
*/
CRITICAL_ERROR();
ret = -RED_EFUBAR;
}
}
return ret;
}
#endif /* REDCONF_READ_ONLY == 0 */
/** @brief Get the allocation state of a block.
Takes into account the allocation bits from both metaroots, and returns one
of four possible allocation state values:
- ::ALLOCSTATE_FREE Free and may be allocated; writeable.
- ::ALLOCSTATE_USED In-use and transacted; not writeable.
- ::ALLOCSTATE_NEW In-use but not transacted; writeable.
- ::ALLOCSTATE_AFREE Will become free after a transaction; not writeable.
@param ulBlock The block number to query.
@param pState On successful return, populated with the state of the block.
@return A negated ::REDSTATUS code indicating the operation result.
@retval 0 Operation was successful.
@retval -RED_EINVAL @p ulBlock is out of range; or @p pState is `NULL`.
@retval -RED_EIO A disk I/O error occurred.
*/
REDSTATUS RedImapBlockState(
uint32_t ulBlock,
ALLOCSTATE *pState)
{
REDSTATUS ret;
if( (ulBlock < gpRedCoreVol->ulInodeTableStartBN)
|| (ulBlock >= gpRedVolume->ulBlockCount)
|| (pState == NULL))
{
REDERROR();
ret = -RED_EINVAL;
}
else
{
bool fBitCurrent;
ret = RedImapBlockGet(gpRedCoreVol->bCurMR, ulBlock, &fBitCurrent);
if(ret == 0)
{
bool fBitOld;
ret = RedImapBlockGet(1U - gpRedCoreVol->bCurMR, ulBlock, &fBitOld);
if(ret == 0)
{
if(fBitCurrent)
{
if(fBitOld)
{
*pState = ALLOCSTATE_USED;
}
else
{
*pState = ALLOCSTATE_NEW;
}
}
else
{
if(fBitOld)
{
*pState = ALLOCSTATE_AFREE;
}
else
{
*pState = ALLOCSTATE_FREE;
}
}
}
}
}
return ret;
}
@@ -0,0 +1,316 @@
/* ----> 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 external imap.
The external imap is used on volumes that are too big for the imap bitmap
to be stored entirely in the metaroot, so instead the bitmap is stored in
imap nodes on disk, and the metaroot bitmap is used to toggle between imap
nodes.
*/
#include <redfs.h>
#if REDCONF_IMAP_EXTERNAL == 1
#include <redcore.h>
#if REDCONF_READ_ONLY == 0
static REDSTATUS ImapNodeBranch(uint32_t ulImapNode, IMAPNODE **ppImap);
static bool ImapNodeIsBranched(uint32_t ulImapNode);
#endif
/** @brief Get the allocation bit of a block from the imap as it exists in
either metaroot.
@param bMR The metaroot index: either 0 or 1.
@param ulBlock The block number to query.
@param pfAllocated On successful exit, 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;
or @p pfAllocated is `NULL`.
@retval -RED_EIO A disk I/O error occurred.
*/
REDSTATUS RedImapEBlockGet(
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
{
uint32_t ulOffset = ulBlock - gpRedCoreVol->ulInodeTableStartBN;
uint32_t ulImapNode = ulOffset / IMAPNODE_ENTRIES;
uint8_t bMRToRead = bMR;
IMAPNODE *pImap;
#if REDCONF_READ_ONLY == 0
/* If the imap node is not branched, then both copies of the imap are
identical. If the old metaroot copy is requested, use the current
copy instead, since it is more likely to be buffered.
*/
if(bMR == (1U - gpRedCoreVol->bCurMR))
{
if(!ImapNodeIsBranched(ulImapNode))
{
bMRToRead = 1U - bMR;
}
}
#endif
ret = RedBufferGet(RedImapNodeBlock(bMRToRead, ulImapNode), BFLAG_META_IMAP, CAST_VOID_PTR_PTR(&pImap));
if(ret == 0)
{
*pfAllocated = RedBitGet(pImap->abEntries, ulOffset % IMAPNODE_ENTRIES);
RedBufferPut(pImap);
}
}
return ret;
}
#if REDCONF_READ_ONLY == 0
/** @brief Set the allocation bit of a block in the working-state imap.
@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.
@retval -RED_EIO A disk I/O error occurred.
*/
REDSTATUS RedImapEBlockSet(
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;
uint32_t ulImapNode = ulOffset / IMAPNODE_ENTRIES;
IMAPNODE *pImap;
ret = ImapNodeBranch(ulImapNode, &pImap);
if(ret == 0)
{
uint32_t ulImapEntry = ulOffset % IMAPNODE_ENTRIES;
if(RedBitGet(pImap->abEntries, ulImapEntry) == fAllocated)
{
/* The driver shouldn't ever set a bit in the imap to its
current value. That shouldn't ever be needed, and it
indicates that the driver is doing unnecessary I/O, or
that the imap is corrupt.
*/
CRITICAL_ERROR();
ret = -RED_EFUBAR;
}
else if(fAllocated)
{
RedBitSet(pImap->abEntries, ulImapEntry);
}
else
{
RedBitClear(pImap->abEntries, ulImapEntry);
}
RedBufferPut(pImap);
}
}
return ret;
}
/** @brief Branch an imap node and get a buffer for it.
If the imap node is already branched, it can be overwritten in its current
location, and this function just gets it buffered dirty. If the node is not
already branched, the metaroot must be updated to toggle the imap node to
its alternate location, thereby preserving the committed state copy of the
imap node.
@param ulImapNode The imap node to branch and buffer.
@param ppImap On successful return, populated with the imap node
buffer, which will be marked dirty.
@return A negated ::REDSTATUS code indicating the operation result.
@retval 0 Operation was successful.
@retval -RED_EINVAL @p ulImapNode is out of range; or @p ppImap is `NULL`.
@retval -RED_EIO A disk I/O error occurred.
*/
static REDSTATUS ImapNodeBranch(
uint32_t ulImapNode,
IMAPNODE **ppImap)
{
REDSTATUS ret;
if((ulImapNode >= gpRedCoreVol->ulImapNodeCount) || (ppImap == NULL))
{
REDERROR();
ret = -RED_EINVAL;
}
else if(ImapNodeIsBranched(ulImapNode))
{
/* Imap node is already branched, so just get it buffered dirty.
*/
ret = RedBufferGet(RedImapNodeBlock(gpRedCoreVol->bCurMR, ulImapNode), BFLAG_META_IMAP | BFLAG_DIRTY, CAST_VOID_PTR_PTR(ppImap));
}
else
{
uint32_t ulBlockCurrent;
uint32_t ulBlockOld;
/* The metaroot currently points to the committed state imap node.
Toggle the metaroot to point at the alternate, writeable location.
*/
if(RedBitGet(gpRedMR->abEntries, ulImapNode))
{
RedBitClear(gpRedMR->abEntries, ulImapNode);
}
else
{
RedBitSet(gpRedMR->abEntries, ulImapNode);
}
ulBlockCurrent = RedImapNodeBlock(gpRedCoreVol->bCurMR, ulImapNode);
ulBlockOld = RedImapNodeBlock(1U - gpRedCoreVol->bCurMR, ulImapNode);
ret = RedBufferDiscardRange(ulBlockCurrent, 1U);
/* Buffer the committed copy then reassign the block number to the
writeable location. This also dirties the buffer.
*/
if(ret == 0)
{
ret = RedBufferGet(ulBlockOld, BFLAG_META_IMAP, CAST_VOID_PTR_PTR(ppImap));
if(ret == 0)
{
RedBufferBranch(*ppImap, ulBlockCurrent);
}
}
}
return ret;
}
/** @brief Determine whether an imap node is branched.
If the imap node is branched, it can be overwritten in its current location.
@param ulImapNode The imap node to examine.
@return Whether the imap node is branched.
*/
static bool ImapNodeIsBranched(
uint32_t ulImapNode)
{
bool fNodeBitSetInMetaroot0 = RedBitGet(gpRedCoreVol->aMR[0U].abEntries, ulImapNode);
bool fNodeBitSetInMetaroot1 = RedBitGet(gpRedCoreVol->aMR[1U].abEntries, ulImapNode);
/* If the imap node is not branched, both metaroots will point to the same
copy of the node.
*/
return fNodeBitSetInMetaroot0 != fNodeBitSetInMetaroot1;
}
#endif /* REDCONF_READ_ONLY == 0 */
/** @brief Calculate the block number of the imap node location indicated by the
given metaroot.
An imap node has two locations on disk. A bit in the metaroot bitmap
indicates which location is the valid one, according to that metaroot. This
function returns the block number of the imap node which is valid in the
given metaroot.
@param bMR Which metaroot to examine.
@param ulImapNode The imap node for which to calculate the block number.
@return Block number of the imap node, as indicated by the given metaroot.
*/
uint32_t RedImapNodeBlock(
uint8_t bMR,
uint32_t ulImapNode)
{
uint32_t ulBlock;
REDASSERT(ulImapNode < gpRedCoreVol->ulImapNodeCount);
ulBlock = gpRedCoreVol->ulImapStartBN + (ulImapNode * 2U);
if(bMR > 1U)
{
REDERROR();
}
else if(RedBitGet(gpRedCoreVol->aMR[bMR].abEntries, ulImapNode))
{
/* Bit is set, so point ulBlock at the second copy of the node.
*/
ulBlock++;
}
else
{
/* ulBlock already points at the first copy of the node.
*/
}
return ulBlock;
}
#endif /* REDCONF_IMAP_EXTERNAL == 1 */
@@ -0,0 +1,133 @@
/* ----> 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 */
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,257 @@
/* ----> 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
*/
#ifndef REDCORE_H
#define REDCORE_H
#include <redstat.h>
#include <redvolume.h>
#include "rednodes.h"
#include "redcoremacs.h"
#include "redcorevol.h"
#define META_SIG_MASTER (0x5453414DU) /* 'MAST' */
#define META_SIG_METAROOT (0x4154454DU) /* 'META' */
#define META_SIG_IMAP (0x50414D49U) /* 'IMAP' */
#define META_SIG_INODE (0x444F4E49U) /* 'INOD' */
#define META_SIG_DINDIR (0x494C4244U) /* 'DBLI' */
#define META_SIG_INDIR (0x49444E49U) /* 'INDI' */
REDSTATUS RedIoRead(uint8_t bVolNum, uint32_t ulBlockStart, uint32_t ulBlockCount, void *pBuffer);
#if REDCONF_READ_ONLY == 0
REDSTATUS RedIoWrite(uint8_t bVolNum, uint32_t ulBlockStart, uint32_t ulBlockCount, const void *pBuffer);
REDSTATUS RedIoFlush(uint8_t bVolNum);
#endif
/** Indicates a block buffer is dirty (its contents are different than the
contents of the corresponding block on disk); or, when passed into
RedBufferGet(), indicates that the buffer should be marked dirty.
*/
#define BFLAG_DIRTY ((uint16_t) 0x0001U)
/** Tells RedBufferGet() that the buffer is for a newly allocated block, and its
contents should be zeroed instead of being read from disk. Always used in
combination with BFLAG_DIRTY.
*/
#define BFLAG_NEW ((uint16_t) 0x0002U)
/** Indicates that a block buffer is a master block (MASTERBLOCK) metadata node.
*/
#define BFLAG_META_MASTER ((uint16_t)(0x0004U | BFLAG_META))
/** Indicates that a block buffer is an imap (IMAPNODE) metadata node.
*/
#define BFLAG_META_IMAP ((uint16_t)(0x0008U | BFLAG_META))
/** Indicates that a block buffer is an inode (INODE) metadata node.
*/
#define BFLAG_META_INODE ((uint16_t)(0x0010U | BFLAG_META))
/** Indicates that a block buffer is an indirect (INDIR) metadata node.
*/
#define BFLAG_META_INDIR ((uint16_t)(0x0020U | BFLAG_META))
/** Indicates that a block buffer is a double indirect (DINDIR) metadata node.
*/
#define BFLAG_META_DINDIR ((uint16_t)(0x0040U | BFLAG_META))
/** Indicates that a block buffer is a metadata node. Callers of RedBufferGet()
should not use this flag; instead, use one of the BFLAG_META_* flags.
*/
#define BFLAG_META ((uint16_t) 0x8000U)
void RedBufferInit(void);
REDSTATUS RedBufferGet(uint32_t ulBlock, uint16_t uFlags, void **ppBuffer);
void RedBufferPut(const void *pBuffer);
#if REDCONF_READ_ONLY == 0
REDSTATUS RedBufferFlush(uint32_t ulBlockStart, uint32_t ulBlockCount);
void RedBufferDirty(const void *pBuffer);
void RedBufferBranch(const void *pBuffer, uint32_t ulBlockNew);
#if (REDCONF_API_POSIX == 1) || FORMAT_SUPPORTED
void RedBufferDiscard(const void *pBuffer);
#endif
#endif
REDSTATUS RedBufferDiscardRange(uint32_t ulBlockStart, uint32_t ulBlockCount);
/** @brief Allocation state of a block.
*/
typedef enum
{
ALLOCSTATE_FREE, /**< Free and may be allocated; writeable. */
ALLOCSTATE_USED, /**< In-use and transacted; not writeable. */
ALLOCSTATE_NEW, /**< In-use but not transacted; writeable. */
ALLOCSTATE_AFREE /**< Will become free after a transaction; not writeable. */
} ALLOCSTATE;
REDSTATUS RedImapBlockGet(uint8_t bMR, uint32_t ulBlock, bool *pfAllocated);
#if REDCONF_READ_ONLY == 0
REDSTATUS RedImapBlockSet(uint32_t ulBlock, bool fAllocated);
REDSTATUS RedImapAllocBlock(uint32_t *pulBlock);
#endif
REDSTATUS RedImapBlockState(uint32_t ulBlock, ALLOCSTATE *pState);
#if REDCONF_IMAP_INLINE == 1
REDSTATUS RedImapIBlockGet(uint8_t bMR, uint32_t ulBlock, bool *pfAllocated);
REDSTATUS RedImapIBlockSet(uint32_t ulBlock, bool fAllocated);
#endif
#if REDCONF_IMAP_EXTERNAL == 1
REDSTATUS RedImapEBlockGet(uint8_t bMR, uint32_t ulBlock, bool *pfAllocated);
REDSTATUS RedImapEBlockSet(uint32_t ulBlock, bool fAllocated);
uint32_t RedImapNodeBlock(uint8_t bMR, uint32_t ulImapNode);
#endif
/** @brief Cached inode structure.
*/
typedef struct
{
uint32_t ulInode; /**< The inode number of the cached inode. */
#if REDCONF_API_POSIX == 1
bool fDirectory; /**< True if the inode is a directory. */
#endif
#if REDCONF_READ_ONLY == 0
bool fBranched; /**< True if the inode is branched (writeable). */
bool fDirty; /**< True if the inode buffer is dirty. */
#endif
bool fCoordInited; /**< True after the first seek. */
INODE *pInodeBuf; /**< Pointer to the inode buffer. */
#if DINDIR_POINTERS > 0U
DINDIR *pDindir; /**< Pointer to the double indirect node buffer. */
#endif
#if REDCONF_DIRECT_POINTERS < INODE_ENTRIES
INDIR *pIndir; /**< Pointer to the indirect node buffer. */
#endif
uint8_t *pbData; /**< Pointer to the data block buffer. */
/* All the members below this point are part of the seek coordinates; see
RedInodeDataSeek().
*/
uint32_t ulLogicalBlock; /**< Logical block offset into the inode. */
#if DINDIR_POINTERS > 0U
uint32_t ulDindirBlock; /**< Physical block number of the double indirect node. */
#endif
#if REDCONF_DIRECT_POINTERS < INODE_ENTRIES
uint32_t ulIndirBlock; /**< Physical block number of the indirect node. */
#endif
uint32_t ulDataBlock; /**< Physical block number of the file data block. */
uint16_t uInodeEntry; /**< Which inode entry to traverse to reach ulLogicalBlock. */
#if DINDIR_POINTERS > 0U
uint16_t uDindirEntry; /**< Which double indirect entry to traverse to reach ulLogicalBlock. */
#endif
#if REDCONF_DIRECT_POINTERS < INODE_ENTRIES
uint16_t uIndirEntry; /**< Which indirect entry to traverse to reach ulLogicalBlock. */
#endif
} CINODE;
#define CINODE_IS_MOUNTED(pInode) (((pInode) != NULL) && INODE_IS_VALID((pInode)->ulInode) && ((pInode)->pInodeBuf != NULL))
#define CINODE_IS_DIRTY(pInode) (CINODE_IS_MOUNTED(pInode) && (pInode)->fDirty)
#define IPUT_UPDATE_ATIME (0x01U)
#define IPUT_UPDATE_MTIME (0x02U)
#define IPUT_UPDATE_CTIME (0x04U)
#define IPUT_UPDATE_MASK (IPUT_UPDATE_ATIME|IPUT_UPDATE_MTIME|IPUT_UPDATE_CTIME)
REDSTATUS RedInodeMount(CINODE *pInode, FTYPE type, bool fBranch);
#if REDCONF_READ_ONLY == 0
REDSTATUS RedInodeBranch(CINODE *pInode);
#endif
#if (REDCONF_READ_ONLY == 0) && ((REDCONF_API_POSIX == 1) || FORMAT_SUPPORTED)
REDSTATUS RedInodeCreate(CINODE *pInode, uint32_t ulPInode, uint16_t uMode);
#endif
#if DELETE_SUPPORTED
REDSTATUS RedInodeDelete(CINODE *pInode);
REDSTATUS RedInodeLinkDec(CINODE *pInode);
#endif
#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX == 1)
REDSTATUS RedInodeFree(CINODE *pInode);
#endif
void RedInodePut(CINODE *pInode, uint8_t bTimeFields);
void RedInodePutCoord(CINODE *pInode);
#if DINDIR_POINTERS > 0U
void RedInodePutDindir(CINODE *pInode);
#endif
#if REDCONF_DIRECT_POINTERS < INODE_ENTRIES
void RedInodePutIndir(CINODE *pInode);
#endif
void RedInodePutData(CINODE *pInode);
#if ((REDCONF_READ_ONLY == 0) && ((REDCONF_API_POSIX == 1) || FORMAT_SUPPORTED)) || (REDCONF_CHECKER == 1)
REDSTATUS RedInodeIsFree(uint32_t ulInode, bool *pfFree);
#endif
REDSTATUS RedInodeBitGet(uint8_t bMR, uint32_t ulInode, uint8_t bWhich, bool *pfAllocated);
REDSTATUS RedInodeDataRead(CINODE *pInode, uint64_t ullStart, uint32_t *pulLen, void *pBuffer);
#if REDCONF_READ_ONLY == 0
REDSTATUS RedInodeDataWrite(CINODE *pInode, uint64_t ullStart, uint32_t *pulLen, const void *pBuffer);
#if DELETE_SUPPORTED || TRUNCATE_SUPPORTED
REDSTATUS RedInodeDataTruncate(CINODE *pInode, uint64_t ullSize);
#endif
#endif
REDSTATUS RedInodeDataSeekAndRead(CINODE *pInode, uint32_t ulBlock);
REDSTATUS RedInodeDataSeek(CINODE *pInode, uint32_t ulBlock);
#if REDCONF_API_POSIX == 1
#if REDCONF_READ_ONLY == 0
REDSTATUS RedDirEntryCreate(CINODE *pPInode, const char *pszName, uint32_t ulInode);
#endif
#if DELETE_SUPPORTED
REDSTATUS RedDirEntryDelete(CINODE *pPInode, uint32_t ulDeleteIdx);
#endif
REDSTATUS RedDirEntryLookup(CINODE *pPInode, const char *pszName, uint32_t *pulEntryIdx, uint32_t *pulInode);
#if (REDCONF_API_POSIX_READDIR == 1) || (REDCONF_CHECKER == 1)
REDSTATUS RedDirEntryRead(CINODE *pPInode, uint32_t *pulIdx, char *pszName, uint32_t *pulInode);
#endif
#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX_RENAME == 1)
REDSTATUS RedDirEntryRename(CINODE *pSrcPInode, const char *pszSrcName, CINODE *pSrcInode, CINODE *pDstPInode, const char *pszDstName, CINODE *pDstInode);
#endif
#endif
REDSTATUS RedVolMount(void);
REDSTATUS RedVolMountMaster(void);
REDSTATUS RedVolMountMetaroot(void);
#if REDCONF_READ_ONLY == 0
REDSTATUS RedVolTransact(void);
#endif
void RedVolCriticalError(const char *pszFileName, uint32_t ulLineNum);
REDSTATUS RedVolSeqNumIncrement(void);
#if FORMAT_SUPPORTED
REDSTATUS RedVolFormat(void);
#endif
#endif
@@ -0,0 +1,92 @@
/* ----> 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
*/
#ifndef REDCOREMACS_H
#define REDCOREMACS_H
#define BLOCK_NUM_MASTER (0UL) /* Block number of the master block. */
#define BLOCK_NUM_FIRST_METAROOT (1UL) /* Block number of the first metaroot. */
#define BLOCK_SPARSE (0U)
#define DINDIR_POINTERS ((INODE_ENTRIES - REDCONF_DIRECT_POINTERS) - REDCONF_INDIRECT_POINTERS)
#define DINDIR_DATA_BLOCKS (INDIR_ENTRIES * INDIR_ENTRIES)
#define INODE_INDIR_BLOCKS (REDCONF_INDIRECT_POINTERS * INDIR_ENTRIES)
#define INODE_DINDIR_BLOCKS (DINDIR_POINTERS * DINDIR_DATA_BLOCKS)
#define INODE_DATA_BLOCKS (REDCONF_DIRECT_POINTERS + INODE_INDIR_BLOCKS + INODE_DINDIR_BLOCKS)
#define INODE_SIZE_MAX (UINT64_SUFFIX(1) * REDCONF_BLOCK_SIZE * INODE_DATA_BLOCKS)
/* First inode number that can be allocated.
*/
#if REDCONF_API_POSIX == 1
#define INODE_FIRST_FREE (INODE_FIRST_VALID + 1U)
#else
#define INODE_FIRST_FREE (INODE_FIRST_VALID)
#endif
/** @brief Determine if an inode number is valid.
*/
#define INODE_IS_VALID(INODENUM) (((INODENUM) >= INODE_FIRST_VALID) && ((INODENUM) < (INODE_FIRST_VALID + gpRedVolConf->ulInodeCount)))
/* The number of blocks reserved to allow a truncate or delete operation to
complete when the disk is otherwise full.
The more expensive of the two operations is delete, which has to actually
write to a file data block to remove the directory entry.
*/
#if REDCONF_READ_ONLY == 1
#define RESERVED_BLOCKS 0U
#elif (REDCONF_API_POSIX == 1) && ((REDCONF_API_POSIX_UNLINK == 1) || (REDCONF_API_POSIX_RMDIR == 1))
#if DINDIR_POINTERS > 0U
#define RESERVED_BLOCKS 3U
#elif REDCONF_INDIRECT_POINTERS > 0U
#define RESERVED_BLOCKS 2U
#else
#define RESERVED_BLOCKS 1U
#endif
#elif ((REDCONF_API_POSIX == 1) && (REDCONF_API_POSIX_FTRUNCATE == 1)) || ((REDCONF_API_FSE == 1) && (REDCONF_API_FSE_TRUNCATE == 1))
#if DINDIR_POINTERS > 0U
#define RESERVED_BLOCKS 2U
#elif REDCONF_INDIRECT_POINTERS > 0U
#define RESERVED_BLOCKS 1U
#else
#define RESERVED_BLOCKS 0U
#endif
#else
#define RESERVED_BLOCKS 0U
#endif
#define CRITICAL_ASSERT(EXP) ((EXP) ? (void)0 : CRITICAL_ERROR())
#define CRITICAL_ERROR() RedVolCriticalError(__FILE__, __LINE__)
#endif
@@ -0,0 +1,95 @@
/* ----> 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
*/
#ifndef REDCOREVOL_H
#define REDCOREVOL_H
/** @brief Per-volume run-time data specific to the core.
*/
typedef struct
{
/** Whether this volume uses the inline imap (true) or external imap
(false). Computed at initialization time based on the block count.
*/
bool fImapInline;
#if REDCONF_IMAP_EXTERNAL == 1
/** First block number of the on-disk imap. Valid only when fImapInline
is false.
*/
uint32_t ulImapStartBN;
/** The number of double-allocated imap nodes that make up the imap.
*/
uint32_t ulImapNodeCount;
#endif
/** Block number where the inode table starts.
*/
uint32_t ulInodeTableStartBN;
/** First block number that can be allocated.
*/
uint32_t ulFirstAllocableBN;
/** The two metaroot structures, committed and working state.
*/
METAROOT aMR[2U];
/** The index of the current metaroot; must be 0 or 1.
*/
uint8_t bCurMR;
/** Whether the volume has been branched or not.
*/
bool fBranched;
/** The number of blocks which will become free after the next transaction.
*/
uint32_t ulAlmostFreeBlocks;
#if RESERVED_BLOCKS > 0U
/** Whether to use the blocks reserved for operations that create free
space.
*/
bool fUseReservedBlocks;
#endif
} COREVOLUME;
/* Pointer to the core volume currently being accessed; populated during
RedCoreVolSetCurrent().
*/
extern COREVOLUME * CONST_IF_ONE_VOLUME gpRedCoreVol;
/* Pointer to the metaroot currently being accessed; populated during
RedCoreVolSetCurrent() and RedCoreVolTransact().
*/
extern METAROOT *gpRedMR;
#endif
@@ -0,0 +1,195 @@
/* ----> 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
*/
#ifndef REDNODES_H
#define REDNODES_H
#define NODEHEADER_SIZE (16U)
#define NODEHEADER_OFFSET_SIG (0U)
#define NODEHEADER_OFFSET_CRC (4U)
#define NODEHEADER_OFFSET_SEQ (8U)
/** @brief Common header for all metadata nodes.
*/
typedef struct
{
uint32_t ulSignature; /**< Value which uniquely identifies the metadata node type. */
uint32_t ulCRC; /**< CRC-32 checksum of the node contents, starting after the CRC. */
uint64_t ullSequence; /**< Current sequence number at the time the node was written to disk. */
} NODEHEADER;
/** Flag set in the master block when REDCONF_API_POSIX == 1. */
#define MBFLAG_API_POSIX (0x01U)
/** Flag set in the master block when REDCONF_INODE_TIMESTAMPS == 1. */
#define MBFLAG_INODE_TIMESTAMPS (0x02U)
/** Flag set in the master block when REDCONF_INODE_BLOCKS == 1. */
#define MBFLAG_INODE_BLOCKS (0x04U)
/** Flag set in the master block when (REDCONF_API_POSIX == 1) && (REDCONF_API_POSIX_LINK == 1). */
#define MBFLAG_INODE_NLINK (0x08U)
/** @brief Node which identifies the volume and stores static volume information.
*/
typedef struct
{
NODEHEADER hdr; /**< Common node header. */
uint32_t ulVersion; /**< On-disk layout version number. */
char acBuildNum[8U]; /**< Build number of the product (not null terminated). */
uint32_t ulFormatTime; /**< Date and time the volume was formatted. */
uint32_t ulInodeCount; /**< Compile-time configured number of inodes. */
uint32_t ulBlockCount; /**< Compile-time configured number of logical blocks. */
uint16_t uMaxNameLen; /**< Compile-time configured maximum file name length. */
uint16_t uDirectPointers; /**< Compile-time configured number of direct pointers per inode. */
uint16_t uIndirectPointers; /**< Compile-time configured number of indirect pointers per inode. */
uint8_t bBlockSizeP2; /**< Compile-time configured block size, expressed as a power of two. */
uint8_t bFlags; /**< Compile-time booleans which affect on-disk structures. */
} MASTERBLOCK;
#if REDCONF_API_POSIX == 1
#define METAROOT_HEADER_SIZE (NODEHEADER_SIZE + 16U) /* Size in bytes of the metaroot header fields. */
#else
#define METAROOT_HEADER_SIZE (NODEHEADER_SIZE + 12U) /* Size in bytes of the metaroot header fields. */
#endif
#define METAROOT_ENTRY_BYTES (REDCONF_BLOCK_SIZE - METAROOT_HEADER_SIZE) /* Number of bytes remaining in the metaroot block for entries. */
#define METAROOT_ENTRIES (METAROOT_ENTRY_BYTES * 8U)
/** @brief Metadata root node; each volume has two.
*/
typedef struct
{
NODEHEADER hdr; /**< Common node header. */
uint32_t ulSectorCRC; /**< CRC-32 checksum of the first sector. */
uint32_t ulFreeBlocks; /**< Number of allocable blocks that are free. */
#if REDCONF_API_POSIX == 1
uint32_t ulFreeInodes; /**< Number of inode slots that are free. */
#endif
uint32_t ulAllocNextBlock; /**< Forward allocation pointer. */
/** Imap bitmap. With inline imaps, this is the imap bitmap that indicates
which inode blocks are used and which allocable blocks are used.
Otherwise, this bitmap toggles nodes in the external imap between one
of two possible block locations.
*/
uint8_t abEntries[METAROOT_ENTRY_BYTES];
} METAROOT;
#if REDCONF_IMAP_EXTERNAL == 1
#define IMAPNODE_HEADER_SIZE (NODEHEADER_SIZE) /* Size in bytes of the imap node header fields. */
#define IMAPNODE_ENTRY_BYTES (REDCONF_BLOCK_SIZE - IMAPNODE_HEADER_SIZE) /* Number of bytes remaining in the imap node for entries. */
#define IMAPNODE_ENTRIES (IMAPNODE_ENTRY_BYTES * 8U)
/** @brief One node of the external imap.
*/
typedef struct
{
NODEHEADER hdr; /**< Common node header. */
/** Bitmap which indicates which inode blocks are used and which allocable
blocks are used.
*/
uint8_t abEntries[IMAPNODE_ENTRY_BYTES];
} IMAPNODE;
#endif
#define INODE_HEADER_SIZE (NODEHEADER_SIZE + 8U + ((REDCONF_INODE_BLOCKS == 1) ? 4U : 0U) + \
((REDCONF_INODE_TIMESTAMPS == 1) ? 12U : 0U) + 4U + ((REDCONF_API_POSIX == 1) ? 4U : 0U))
#define INODE_ENTRIES ((REDCONF_BLOCK_SIZE - INODE_HEADER_SIZE) / 4U)
#if (REDCONF_DIRECT_POINTERS < 0) || (REDCONF_DIRECT_POINTERS > (INODE_ENTRIES - REDCONF_INDIRECT_POINTERS))
#error "Configuration error: invalid value of REDCONF_DIRECT_POINTERS"
#endif
#if (REDCONF_INDIRECT_POINTERS < 0) || (REDCONF_INDIRECT_POINTERS > (INODE_ENTRIES - REDCONF_DIRECT_POINTERS))
#error "Configuration error: invalid value of REDCONF_INDIRECT_POINTERS"
#endif
/** @brief Stores metadata for a file or directory.
*/
typedef struct
{
NODEHEADER hdr; /**< Common node header. */
uint64_t ullSize; /**< Size of the inode, in bytes. */
#if REDCONF_INODE_BLOCKS == 1
uint32_t ulBlocks; /**< Total number file data blocks allocated to the inode. */
#endif
#if REDCONF_INODE_TIMESTAMPS == 1
uint32_t ulATime; /**< Time of last access (seconds since January 1, 1970). */
uint32_t ulMTime; /**< Time of last modification (seconds since January 1, 1970). */
uint32_t ulCTime; /**< Time of last status change (seconds since January 1, 1970). */
#endif
uint16_t uMode; /**< Inode type (file or directory) and permissions (reserved). */
#if (REDCONF_API_POSIX == 1) && (REDCONF_API_POSIX_LINK == 1)
uint16_t uNLink; /**< Link count, number of names pointing to the inode. */
#else
uint8_t abPadding[2]; /**< Padding to 32-bit align the next member. */
#endif
#if REDCONF_API_POSIX == 1
uint32_t ulPInode; /**< Parent inode number. Only guaranteed to be accurate for directories. */
#endif
/** Block numbers for lower levels of the file metadata structure. Some
fraction of these entries are for direct pointers (file data block
numbers), some for indirect pointers, some for double-indirect
pointers; the number allocated to each is static but user-configurable.
For all types, an array slot is zero if the range is sparse or beyond
the end of file.
*/
uint32_t aulEntries[INODE_ENTRIES];
} INODE;
#define INDIR_HEADER_SIZE (NODEHEADER_SIZE + 4U)
#define INDIR_ENTRIES ((REDCONF_BLOCK_SIZE - INDIR_HEADER_SIZE) / 4U)
/** @brief Node for storing block pointers.
*/
typedef struct
{
NODEHEADER hdr; /**< Common node header. */
uint32_t ulInode; /**< Inode which owns this indirect or double indirect. */
/** For indirect nodes, stores block numbers of file data. For double
indirect nodes, stores block numbers of indirect nodes. An array
slot is zero if the corresponding block or indirect range is beyond
the end of file or entirely sparse.
*/
uint32_t aulEntries[INDIR_ENTRIES];
} INDIR, DINDIR;
#endif
@@ -0,0 +1,389 @@
Datalight Coding Style
======================
This is a description of the Datalight Coding Style intended for third parties
who want to contribute code to Reliance Edge. This document is derived from the
DDSS Coding Guidelines, but only contains a subset of the content which is most
likely to be relevant to third party contributors.
Reliance Edge complies with the MISRA-C:2012 coding guidelines, which includes
many rules that affect coding style. Unfortunately the MISRA-C:2012 document is
not freely available, and is much too long to be effectively summarized, but if
you are familiar with the rules, adhere to them. A few important rules of
thumb: avoid the goto and continue keywords; avoid using more than one break
in a loop; and avoid having more than one return from a function (single point
of exit); default cases in every switch statement; avoid recursion; and make
generous use of parentheses. Outside of the file system driver, in tests and
host tools, the MISRA-C rules are relaxed.
Beyond MISRA-C, Datalight has a standard coding style. Most aspects of this
style are matters of preference, but when contributing code to Datalight an
effort should be made to use this style for the sake of consistency.
Below is an example function, which illustrates several key points of Datalight
Coding Style:
/** @brief One-sentence description of what this function does.
Additional description.
@param ulFirstParameter Description of the parameter.
@param pszPointer Description of the parameter.
@return Describe the return value.
@retval true Optional description of specific return value.
@retval false Optional description of specific return value.
*/
bool ExampleFunction(
uint32_t ulFirstParameter,
char *pszPointer)
{
bool fStatus = true;
/* This is a single-line comment.
*/
if(ulFirstParameter > 0U)
{
/* This is a multi-line comment. Filler text: Lorem ipsum dolor sit
amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt
ut labore et dolore magna aliqua.
*/
FunctionCall();
while(fStatus)
{
fStatus = AnotherFunction(ulFirstParameter, pszPointer);
}
}
return fStatus;
}
Tab Stop Conventions
--------------------
In all C code (.c/.h), use a tab width of four spaces, and use soft tabs (in
other words, tabs are expanded to spaces). In Makefiles, use hard tabs and a
tab width of 8.
Naming
------
Datalight uses CamelCase for functions and variables. Type names are generally
UPPERCASE, except for standard types like uint32_t. Preprocessor macros are
UPPERCASE, with words separated by underscores (for example, INODE_INVALID).
Doxygen Documentation
---------------------
Doxygen is used to document functions (including static functions), along with
types, structures, files, etc. For Doxygen tags, use '@' instead of a backslash
(thus "@param" not "\param").
Function Declarations
---------------------
Multi-line function declarations are preferred, as they tend to be more
readable. Use the following form:
static bool ExampleFunctionDeclaration(
uint32_t ulFirstParameter,
char *pszPointer,
uint8_t **ppbBuffer)
{
uint16_t uLocalVar; /* descriptive comment */
uint8_t *pbBuffer = NULL; /* descriptive comment */
Function body...
}
The following guidelines should be used:
- Align both the data-type and the variable names, for parameters and locals, at
the same level if practical.
- For pointer types, the '*' belongs to the variable name---it's not part of the
data-type, so keep it with the variable name.
- If useful, single line comments may be used to describe local variables (not
a requirement).
- For functions with no parameters, the "void" declaration does not need to be
on a separate line.
- Generally each variable should be declared on a separate line. This promotes
readability, and facilitates having a comment for each variable.
Function declarations should be spaced apart by two blank lines between the
closing brace which ends a function and the Doxygen comment which starts the
next.
Curly Braces
------------
Datalight lines up all curly braces vertically. As per MISRA-C, curly braces
are never omitted, even if the braces contain only a single statement.
For consistency, even structure declarations and initializations should use the
same style, with the curly braces lined up vertically. One exception is for
structure initializations where both the opening and closing curly braces can
fit on the same line. If so, do it.
Code Comments
-------------
Datalight uses the standard C style /* comments */. C++ style comments (//) are
never used. The Datalight standard comment style is shown below. This style
applies to all general comments within the code.
/* This is a single-line comment.
*/
if(ulFirstParameter > 0U)
{
/* This is a multi-line comment. Filler text: Lorem ipsum dolor sit amet,
consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore
et dolore magna aliqua.
*/
while(fStatus)
{
}
}
Note the characteristics:
- The /* and */ align with the natural 4 character indentation.
- The comment text is exactly indented another 4 characters.
- The comment text starts on the same line as the opening /*.
- The terminating */ is on its own line.
- There is usually a single blank line preceding the comment, however if the
preceding line is an opening curly brace, then an extra blank line is not
necessary.
- There is usually no blank line after the comment, but rather the closing */
"attaches" the comment to the code about which the comment refers.
- These comments should always fit with the standard 80 character margin.
Comments where the /* and */ are on the same line may be used in a few places:
- For variable or parameter descriptions, where the comment fits on the same
line as the declaration.
- For structure member declarations, where the comment fits on the same line as
the declaration.
- For macros or preprocessor logic, where the comment fits on the same line.
It is OK for such comments to exceed the 80 character margin by a small amount,
if necessary, as this sometimes promotes code readability.
Indentation Style
-----------------
The general paradigm used in Datalight code is that curly braces line up
vertically, and everything in between them is indented. This should include all
comments, labels, and preprocessor symbols. The only things which are aligned
at the left-most columns are:
- Symbols, variables, declarations, and preprocessor logic which are at the
module-scope (outside of a function)
- Comments which are outside of a function
- Function declarations
- Function open and closing curly braces
Typically comments are always lined up directly with the code to which they
apply.
Labels (when used; gotos are disallowed in driver code) are lined up two
characters to the left of the code they reside in, to make them stand out, while
as the same time, still remaining subservient to the level of curly braces in
which they reside. For example:
bool ExampleLabelUsage(void)
{
MutexLock();
Lots of complicated code...
Unlock:
MutexUnlock();
return fSuccess;
}
Preprocessor logic, such as controlling features which are conditionally
compiled in or out, should not disrupt the flow of the code, but rather should
be indented in similar fashion to the code it controls, but positioned two
characters to the left. For example, consider the following code snippet. The
preprocessor conditions are both indented relative to the outer curly braces,
but do not disrupt the normal code flow.
int32_t red_statvfs(
const char *pszVolume,
REDSTATFS *pStatvfs)
{
REDSTATUS ret;
ret = PosixEnter();
if(ret == 0)
{
uint8_t bVolNum;
ret = RedPathSplit(pszVolume, &bVolNum, NULL);
#if REDCONF_VOLUME_COUNT > 1U
if(ret == 0)
{
ret = RedCoreVolSetCurrent(bVolNum);
}
#endif
if(ret == 0)
{
ret = RedCoreVolStat(pStatvfs);
}
PosixLeave();
}
return PosixReturn(ret);
}
Note that, like anything else between curly brackets, the contents of a switch
statement are indented:
switch(ulSignature)
{
case META_SIG_MASTER:
fValid = (uFlags == BFLAG_META_MASTER);
break;
case META_SIG_IMAP:
fValid = (uFlags == BFLAG_META_IMAP);
break;
case META_SIG_INODE:
fValid = (uFlags == BFLAG_META_INODE);
break;
case META_SIG_DINDIR:
fValid = (uFlags == BFLAG_META_DINDIR);
break;
case META_SIG_INDIR:
fValid = (uFlags == BFLAG_META_INDIR);
break;
default:
fValid = false;
break;
}
Maximum Line Length
-------------------
The maximum line length for code need not be rigidly limited to the traditional
80 characters. Nevertheless the line lengths should be kept reasonable.
Anything longer than 100 to 120 characters should probably be broken up. The
most important consideration is readability---fitting on the screen is important
for readability, but equally important is facilitating an easy understanding of
the logical code flow.
There are a few exceptions on both sides of the issue. Generally comments
should be limited to 80 characters always. Some lines of code may exceed the
120 character length by a large margin, if it makes the code more understandable
and maintainable. This is especially true when dealing with code that generates
output which needs to be lined up.
Regardless of everything else, no lines should exceed 250 characters because
some editors cannot handle anything larger.
Maximum Display Output Line Length
----------------------------------
Any code which displays TTY style output, whether on a screen or a terminal,
should be constructed so the output is readable and wraps properly on an 80
character wide display. This primarily applies to the "standard" output from
various tests and tools as well as syntax output for those tests and tools;
debug output can violate this rule.
Preprocessor Notation
---------------------
Don't use preprocessor notation where the # is separated from the keyword by one
or more white spaces. For example, don't do:
#ifndef SYMBOL1
# define SYMBOL1
#endif
Instead, do:
#ifndef SYMBOL1
#define SYMBOL1
#endif
Hexadecimal Notation
--------------------
Use uppercase for any alphabetic hexadecimal digits, and lower case for the
notational element. For example:
#define HEXNUM 0x123abd /* Bad */
#define HEXNUM 0X123ABD /* Bad */
#define HEXNUM 0x123ABD /* Good */
Hungarian Notation
------------------
Datalight uses Hungarian notation. The following type prefixes are used:
Type Prefix | Meaning
----------- | -------
c | char
uc | unsigned char
i | int
n | unsigned int or size_t
b | uint8_t
u | uint16_t
ul | uint32_t
ull | uint64_t
sz | array of char that will be null-terminated
f | bool
h | A handle
fn | A function (always used with the "p" modifier)
There is no official Hungarian for int8_t, int16_t, int32_t, or int64_t,
although some code uses unofficial variants (like "ll" for int64_t).
The following modifiers may be used in combination with the type prefixes
defined above, or in combination with other types:
Modifier | Meaning
-------- | -------
a | An array
p | A pointer
g | A global variable
Notes:
- There is no standard Hungarian for structure declarations, however the use of
the "a" and "p" modifiers is completely appropriate (and expected).
- For those data types which do not have any standard defined Hungarian prefix,
using none is preferable to misusing another prefix which would lead to
confusion.
- The "p" pointer modifier must be used such that a variable which is a pointer
to a pointer uses multiple "p" prefixes. A general rule-of-thumb is that the
variable name should have the same number of "p" prefixes as the declaration
has asterisks. This allows pointer expressions to be easily decoded using
cancellation.
Variable Scope
--------------
Declare a variable in the narrowest scope in which it is meaningful.
Unnecessarily declaring all variables at the beginning of a function, where they
may be physically far from where they are actually used, makes the code harder
to maintain.
When multiple blocks of code share a variable, but not its value, declare the
variable separately for each code block.
For example, if two separate blocks contain loops indexed by a variable ulIndex
declare it separately in each block rather than declaring it once in a wider
scope and using it in both places.
Using distinct declarations in the two blocks allows the compiler to check for
failure to initialize the variable in the second block. If there is a single
declaration, the (now meaningless) value left over from the first block can be
used erroneously in the second block.
@@ -0,0 +1,61 @@
# Reliance Edge Release Notes
This file contains a list of updates made to Reliance Edge over the course of
recent releases and a list of known issues.
## Release History and Changes
### Reliance Edge v1.0, July 2015
#### Common Code Changes
- First release of commercial kit and MISRA C:2012 Design Assurance Package.
The commercial kit includes many new tools and tests which were not previously
available.
- Overhauled parsing of command-line parameters to be consistent for all tools
and tests. Command-line tools now use Unix-style short and long options (such
as `-H` and `--help`) instead of DOS-style switches (such as `/?`).
- Renamed all os/\*/include/ostypes.h headers to os/\*/include/redostypes.h, so
that all headers use the product prefix. If you created a port using v0.9,
this header needs to be renamed and its header guard (#ifndef OSTYPES_H etc.)
should also be updated.
- Add a new header for OS-specific MISRA C:2012 deviation macros, located at
os/\*/include/redosdeviations.h. If you created a port using v0.9, copy the
template from os/stub/include/redosdeviations.h into the include directory.
- Eliminated support for sector sizes less than 256. If using a smaller sector
size (say for a RAM disk), this must now be emulated in the implementation of
the block device OS service.
- Added RedFseFormat() as an optional FSE API, allowing FSE applications to
format the volume at run-time.
- This added a new macro to redconf.h: existing redconf.h files from v0.9 must
be updated to work with v1.0. Open redconf.h with the configuration tool,
ignore the warning about the missing macro, and save it.
- Internal restructuring has renamed the macros for the string and memory
functions used in redconf.h. An existing redconf.h file from v0.9 will need
to be updated; for a file containing the old names, the new config tool will
default to using the (slow) Reliance Edge string/memory functions; to use the
C library or custom versions, this will need to be selected in the
configuration utility.
- Fix a bug which would result in an error when attempting to create a name with
one or more trailing path separators (such as `red_mkdir("/foo/bar/")`).
- Fix a bug where an open handle for an inode on one volume would prevent the
same inode number from being deleted on a different volume.
#### FreeRTOS Port Changes
- The implementation of the timestamp OS service no longer requires that
`configUSE_TIMERS` be set to `1`.
### Reliance Edge v0.9 (Beta), April 2015
First public release.
## Known Issues
### Visual Studio 2005
The Reliance Edge Win32 port (used for the host tools and the Win32 test
project) cannot be compiled by Visual Studio 2005. This is not going to be
fixed since VS2005 is an old toolset. Newer versions of Visual Studio, starting
with Visual Studio 2008, work just fine.
@@ -0,0 +1,71 @@
RELIANCE EDGE RELEASE NOTES
This file contains a list of updates made to Reliance Edge over the
course of recent releases and a list of known issues.
Release History and Changes
Reliance Edge v1.0, July 2015
Common Code Changes
- First release of commercial kit and MISRA C:2012 Design
Assurance Package. The commercial kit includes many new tools and
tests which were not previously available.
- Overhauled parsing of command-line parameters to be consistent for
all tools and tests. Command-line tools now use Unix-style short and
long options (such as -H and --help) instead of DOS-style switches
(such as /?).
- Renamed all os/*/include/ostypes.h headers to
os/*/include/redostypes.h, so that all headers use the
product prefix. If you created a port using v0.9, this header needs
to be renamed and its header guard (#ifndef OSTYPES_H etc.) should
also be updated.
- Add a new header for OS-specific MISRA C:2012 deviation macros,
located at os/*/include/redosdeviations.h. If you created a port
using v0.9, copy the template from os/stub/include/redosdeviations.h
into the include directory.
- Eliminated support for sector sizes less than 256. If using a
smaller sector size (say for a RAM disk), this must now be emulated
in the implementation of the block device OS service.
- Added RedFseFormat() as an optional FSE API, allowing FSE
applications to format the volume at run-time.
- This added a new macro to redconf.h: existing redconf.h files from
v0.9 must be updated to work with v1.0. Open redconf.h with the
configuration tool, ignore the warning about the missing macro, and
save it.
- Internal restructuring has renamed the macros for the string and
memory functions used in redconf.h. An existing redconf.h file from
v0.9 will need to be updated; for a file containing the old names,
the new config tool will default to using the (slow) Reliance Edge
string/memory functions; to use the C library or custom versions,
this will need to be selected in the configuration utility.
- Fix a bug which would result in an error when attempting to create a
name with one or more trailing path separators (such as
red_mkdir("/foo/bar/")).
- Fix a bug where an open handle for an inode on one volume would
prevent the same inode number from being deleted on a
different volume.
FreeRTOS Port Changes
- The implementation of the timestamp OS service no longer requires
that configUSE_TIMERS be set to 1.
Reliance Edge v0.9 (Beta), April 2015
First public release.
Known Issues
Visual Studio 2005
The Reliance Edge Win32 port (used for the host tools and the Win32 test
project) cannot be compiled by Visual Studio 2005. This is not going to
be fixed since VS2005 is an old toolset. Newer versions of Visual
Studio, starting with Visual Studio 2008, work just fine.
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,112 @@
/* ----> 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 Defines macros used to interact with the Reliance Edge API.
*/
#ifndef REDAPIMACS_H
#define REDAPIMACS_H
/** Clear all events: manual transactions only. */
#define RED_TRANSACT_MANUAL 0x00000000U
/** Transact prior to unmounting in red_umount() or RedFseUnmount(). */
#define RED_TRANSACT_UMOUNT 0x00000001U
/** Transact after a successful red_open() which created a file. */
#define RED_TRANSACT_CREAT 0x00000002U
/** Transact after a successful red_unlink() or red_rmdir(). */
#define RED_TRANSACT_UNLINK 0x00000004U
/** Transact after a successful red_mkdir(). */
#define RED_TRANSACT_MKDIR 0x00000008U
/** Transact after a successful red_rename(). */
#define RED_TRANSACT_RENAME 0x00000010U
/** Transact after a successful red_link(). */
#define RED_TRANSACT_LINK 0x00000020U
/** Transact after a successful red_close(). */
#define RED_TRANSACT_CLOSE 0x00000040U
/** Transact after a successful red_write() or RedFseWrite(). */
#define RED_TRANSACT_WRITE 0x00000080U
/** Transact after a successful red_fsync(). */
#define RED_TRANSACT_FSYNC 0x00000100U
/** Transact after a successful red_ftruncate(), RedFseTruncate(), or red_open() with RED_O_TRUNC that actually truncates. */
#define RED_TRANSACT_TRUNCATE 0x00000200U
/** Transact to free space in disk full situations. */
#define RED_TRANSACT_VOLFULL 0x00000400U
#if REDCONF_READ_ONLY == 1
/** Mask of all supported automatic transaction events. */
#define RED_TRANSACT_MASK 0U
#elif REDCONF_API_POSIX == 1
/** @brief Mask of all supported automatic transaction events.
*/
#define RED_TRANSACT_MASK \
( \
RED_TRANSACT_UMOUNT | \
RED_TRANSACT_CREAT | \
((REDCONF_API_POSIX_UNLINK == 1) ? RED_TRANSACT_UNLINK : 0U) | \
((REDCONF_API_POSIX_MKDIR == 1) ? RED_TRANSACT_MKDIR : 0U) | \
((REDCONF_API_POSIX_RENAME == 1) ? RED_TRANSACT_RENAME : 0U) | \
((REDCONF_API_POSIX_LINK == 1) ? RED_TRANSACT_LINK : 0U) | \
RED_TRANSACT_CLOSE | \
RED_TRANSACT_WRITE | \
RED_TRANSACT_FSYNC | \
((REDCONF_API_POSIX_FTRUNCATE == 1) ? RED_TRANSACT_TRUNCATE : 0U) | \
RED_TRANSACT_VOLFULL \
)
#else /* REDCONF_API_FSE == 1 */
/** @brief Mask of all supported automatic transaction events.
*/
#define RED_TRANSACT_MASK \
( \
RED_TRANSACT_UMOUNT | \
RED_TRANSACT_WRITE | \
((REDCONF_API_FSE_TRUNCATE == 1) ? RED_TRANSACT_TRUNCATE : 0U) | \
RED_TRANSACT_VOLFULL \
)
#endif /* REDCONF_READ_ONLY */
#if (REDCONF_TRANSACT_DEFAULT & RED_TRANSACT_MASK) != REDCONF_TRANSACT_DEFAULT
#error "Configuration error: invalid value of REDCONF_TRANSACT_DEFAULT"
#endif
#endif
@@ -0,0 +1,317 @@
/* ----> 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 Compile-time validity checks for the REDCONF macros.
*/
#ifndef REDCONFIGCHK_H
#define REDCONFIGCHK_H
#ifndef REDCONF_READ_ONLY
#error "Configuration error: REDCONF_READ_ONLY must be defined."
#endif
#ifndef REDCONF_API_POSIX
#error "Configuration error: REDCONF_API_POSIX must be defined."
#endif
#ifndef REDCONF_API_FSE
#error "Configuration error: REDCONF_API_FSE must be defined."
#endif
#if REDCONF_API_POSIX == 1
#ifndef REDCONF_API_POSIX_FORMAT
#error "Configuration error: REDCONF_API_POSIX_FORMAT must be defined."
#endif
#ifndef REDCONF_API_POSIX_UNLINK
#error "Configuration error: REDCONF_API_POSIX_UNLINK must be defined."
#endif
#ifndef REDCONF_API_POSIX_MKDIR
#error "Configuration error: REDCONF_API_POSIX_MKDIR must be defined."
#endif
#ifndef REDCONF_API_POSIX_RMDIR
#error "Configuration error: REDCONF_API_POSIX_RMDIR must be defined."
#endif
#ifndef REDCONF_API_POSIX_RENAME
#error "Configuration error: REDCONF_API_POSIX_RENAME must be defined."
#endif
#ifndef REDCONF_API_POSIX_LINK
#error "Configuration error: REDCONF_API_POSIX_LINK must be defined."
#endif
#ifndef REDCONF_API_POSIX_FTRUNCATE
#error "Configuration error: REDCONF_API_POSIX_FTRUNCATE must be defined."
#endif
#ifndef REDCONF_API_POSIX_READDIR
#error "Configuration error: REDCONF_API_POSIX_READDIR must be defined."
#endif
#ifndef REDCONF_NAME_MAX
#error "Configuration error: REDCONF_NAME_MAX must be defined."
#endif
#ifndef REDCONF_PATH_SEPARATOR
#error "Configuration error: REDCONF_PATH_SEPARATOR must be defined."
#endif
#ifndef REDCONF_RENAME_ATOMIC
#error "Configuration error: REDCONF_RENAME_ATOMIC must be defined."
#endif
#ifndef REDCONF_HANDLE_COUNT
#error "Configuration error: REDCONF_HANDLE_COUNT must be defined."
#endif
#endif
#if REDCONF_API_FSE == 1
#ifndef REDCONF_API_FSE_FORMAT
#error "Configuration error: REDCONF_API_FSE_FORMAT must be defined."
#endif
#ifndef REDCONF_API_FSE_TRUNCATE
#error "Configuration error: REDCONF_API_FSE_TRUNCATE must be defined."
#endif
#ifndef REDCONF_API_FSE_TRANSMASKSET
#error "Configuration error: REDCONF_API_FSE_TRANSMASKSET must be defined."
#endif
#ifndef REDCONF_API_FSE_TRANSMASKGET
#error "Configuration error: REDCONF_API_FSE_TRANSMASKGET must be defined."
#endif
#endif
#ifndef REDCONF_TASK_COUNT
#error "Configuration error: REDCONF_TASK_COUNT must be defined."
#endif
#ifndef REDCONF_ENDIAN_BIG
#error "Configuration error: REDCONF_ENDIAN_BIG must be defined."
#endif
#ifndef REDCONF_ALIGNMENT_SIZE
#error "Configuration error: REDCONF_ALIGNMENT_SIZE must be defined."
#endif
#ifndef REDCONF_CRC_ALGORITHM
#error "Configuration error: REDCONF_CRC_ALGORITHM must be defined."
#endif
#ifndef REDCONF_INODE_TIMESTAMPS
#error "Configuration error: REDCONF_INODE_TIMESTAMPS must be defined."
#endif
#ifndef REDCONF_ATIME
#error "Configuration error: REDCONF_ATIME must be defined."
#endif
#ifndef REDCONF_DIRECT_POINTERS
#error "Configuration error: REDCONF_DIRECT_POINTERS must be defined."
#endif
#ifndef REDCONF_INDIRECT_POINTERS
#error "Configuration error: REDCONF_INDIRECT_POINTERS must be defined."
#endif
#ifndef REDCONF_INODE_BLOCKS
#error "Configuration error: REDCONF_INODE_BLOCKS must be defined."
#endif
#ifndef REDCONF_IMAP_EXTERNAL
#error "Configuration error: REDCONF_IMAP_EXTERNAL must be defined."
#endif
#ifndef REDCONF_IMAP_INLINE
#error "Configuration error: REDCONF_IMAP_INLINE must be defined."
#endif
#ifndef REDCONF_OUTPUT
#error "Configuration error: REDCONF_OUTPUT must be defined."
#endif
#ifndef REDCONF_ASSERTS
#error "Configuration error: REDCONF_ASSERTS must be defined."
#endif
#ifndef REDCONF_TRANSACT_DEFAULT
#error "Configuration error: REDCONF_TRANSACT_DEFAULT must be defined."
#endif
#ifndef REDCONF_BUFFER_COUNT
#error "Configuration error: REDCONF_BUFFER_COUNT must be defined."
#endif
#ifndef REDCONF_BLOCK_SIZE
#error "Configuration error: REDCONF_BLOCK_SIZE must be defined."
#endif
#ifndef REDCONF_VOLUME_COUNT
#error "Configuration error: REDCONF_VOLUME_COUNT must be defined."
#endif
#ifndef REDCONF_IMAGE_BUILDER
#error "Configuration error: REDCONF_IMAGE_BUILDER must be defined."
#endif
#ifndef REDCONF_CHECKER
#error "Configuration error: REDCONF_CHECKER must be defined."
#endif
#if (REDCONF_READ_ONLY != 0) && (REDCONF_READ_ONLY != 1)
#error "Configuration error: REDCONF_READ_ONLY must be either 0 or 1"
#endif
#if (REDCONF_API_POSIX != 0) && (REDCONF_API_POSIX != 1)
#error "Configuration error: REDCONF_API_POSIX must be either 0 or 1."
#endif
#if (REDCONF_API_FSE != 0) && (REDCONF_API_FSE != 1)
#error "Configuration error: REDCONF_API_FSE must be either 0 or 1."
#endif
#if (REDCONF_API_FSE == 0) && (REDCONF_API_POSIX == 0)
#error "Configuration error: either REDCONF_API_FSE or REDCONF_API_POSIX must be set to 1."
#endif
#if REDCONF_API_POSIX == 1
#if REDCONF_API_FSE != 0
#error "Configuration error: REDCONF_API_FSE must be 0 if REDCONF_API_POSIX is 1"
#endif
#if (REDCONF_API_POSIX_FORMAT != 0) && (REDCONF_API_POSIX_FORMAT != 1)
#error "Configuration error: REDCONF_API_POSIX_FORMAT must be either 0 or 1."
#endif
#if (REDCONF_API_POSIX_UNLINK != 0) && (REDCONF_API_POSIX_UNLINK != 1)
#error "Configuration error: REDCONF_API_POSIX_UNLINK must be either 0 or 1."
#endif
#if (REDCONF_API_POSIX_MKDIR != 0) && (REDCONF_API_POSIX_MKDIR != 1)
#error "Configuration error: REDCONF_API_POSIX_MKDIR must be either 0 or 1."
#endif
#if (REDCONF_API_POSIX_RMDIR != 0) && (REDCONF_API_POSIX_RMDIR != 1)
#error "Configuration error: REDCONF_API_POSIX_RMDIR must be either 0 or 1."
#endif
#if (REDCONF_API_POSIX_RENAME != 0) && (REDCONF_API_POSIX_RENAME != 1)
#error "Configuration error: REDCONF_API_POSIX_RENAME must be either 0 or 1."
#endif
#if (REDCONF_API_POSIX_LINK != 0) && (REDCONF_API_POSIX_LINK != 1)
#error "Configuration error: REDCONF_API_POSIX_LINK must be either 0 or 1."
#endif
#if (REDCONF_API_POSIX_FTRUNCATE != 0) && (REDCONF_API_POSIX_FTRUNCATE != 1)
#error "Configuration error: REDCONF_API_POSIX_FTRUNCATE must be either 0 or 1."
#endif
#if (REDCONF_API_POSIX_READDIR != 0) && (REDCONF_API_POSIX_READDIR != 1)
#error "Configuration error: REDCONF_API_POSIX_READDIR must be either 0 or 1."
#endif
#if (REDCONF_NAME_MAX < 1U) || (REDCONF_NAME_MAX > (REDCONF_BLOCK_SIZE - 4U))
#error "Configuration error: invalid value of REDCONF_NAME_MAX"
#endif
#if (REDCONF_PATH_SEPARATOR < 1) || (REDCONF_PATH_SEPARATOR > 127)
#error "Configuration error: invalid value of REDCONF_PATH_SEPARATOR"
#endif
#if (REDCONF_RENAME_ATOMIC != 0) && (REDCONF_RENAME_ATOMIC != 1)
#error "Configuration error: REDCONF_RENAME_ATOMIC must be either 0 or 1."
#endif
#if (REDCONF_HANDLE_COUNT < 1U) || (REDCONF_HANDLE_COUNT > 4096U)
#error "Configuration error: invalid value of REDCONF_HANDLE_COUNT"
#endif
#endif
#if REDCONF_API_FSE == 1
#if (REDCONF_API_FSE_FORMAT != 0) && (REDCONF_API_FSE_FORMAT != 1)
#error "Configuration error: REDCONF_API_FSE_FORMAT must be either 0 or 1."
#endif
#if (REDCONF_API_FSE_TRUNCATE != 0) && (REDCONF_API_FSE_TRUNCATE != 1)
#error "Configuration error: REDCONF_API_FSE_TRUNCATE must be either 0 or 1."
#endif
#if (REDCONF_API_FSE_TRANSMASKSET != 0) && (REDCONF_API_FSE_TRANSMASKSET != 1)
#error "Configuration error: REDCONF_API_FSE_TRANSMASKSET must be either 0 or 1."
#endif
#if (REDCONF_API_FSE_TRANSMASKGET != 0) && (REDCONF_API_FSE_TRANSMASKGET != 1)
#error "Configuration error: REDCONF_API_FSE_TRANSMASKGET must be either 0 or 1."
#endif
#endif
#if REDCONF_TASK_COUNT < 1U
#error "Configuration error: invalid value of REDCONF_TASK_COUNT"
#endif
#if (REDCONF_ENDIAN_BIG != 0) && (REDCONF_ENDIAN_BIG != 1)
#error "Configuration error: REDCONF_ENDIAN_BIG must be either 0 or 1."
#endif
#if (REDCONF_ALIGNMENT_SIZE != 1U) && (REDCONF_ALIGNMENT_SIZE != 2U) && (REDCONF_ALIGNMENT_SIZE != 4U) && (REDCONF_ALIGNMENT_SIZE != 8U)
#error "Configuration error: invalid value REDCONF_ALIGNMENT_SIZE"
#endif
/* REDCONF_CRC_ALGORITHM checked in crc.c
*/
#if (REDCONF_INODE_TIMESTAMPS != 0) && (REDCONF_INODE_TIMESTAMPS != 1)
#error "Configuration error: REDCONF_INODE_TIMESTAMPS must be either 0 or 1."
#endif
#if (REDCONF_ATIME != 0) && (REDCONF_ATIME != 1)
#error "Configuration error: REDCONF_ATIME must be either 0 or 1."
#endif
#if (REDCONF_INODE_TIMESTAMPS == 0) && (REDCONF_ATIME == 1)
#error "Configuration error: REDCONF_ATIME must be 0 when REDCONF_INODE_TIMESTAMPS is 0."
#endif
/* REDCONF_DIRECT_POINTERS and REDCONF_INDIRECT_POINTERS checked in rednodes.h
*/
#if (REDCONF_INODE_BLOCKS != 0) && (REDCONF_INODE_BLOCKS != 1)
#error "Configuration error: REDCONF_INODE_BLOCKS must be either 0 or 1."
#endif
/* Further validity checking of imap specs done in RelCoreInit()
*/
#if (REDCONF_IMAP_EXTERNAL != 0) && (REDCONF_IMAP_EXTERNAL != 1)
#error "Configuration error: REDCONF_IMAP_EXTERNAL must be either 0 or 1."
#endif
#if (REDCONF_IMAP_INLINE != 0) && (REDCONF_IMAP_INLINE != 1)
#error "Configuration error: REDCONF_IMAP_INLINE must be either 0 or 1."
#endif
#if (REDCONF_IMAP_INLINE == 0) && (REDCONF_IMAP_EXTERNAL == 0)
#error "Configuration error: At least one of REDCONF_IMAP_INLINE and REDCONF_IMAP_EXTERNAL must be set"
#endif
#if (REDCONF_OUTPUT != 0) && (REDCONF_OUTPUT != 1)
#error "Configuration error: REDCONF_OUTPUT must be either 0 or 1."
#endif
#if (REDCONF_ASSERTS != 0) && (REDCONF_ASSERTS != 1)
#error "Configuration error: REDCONF_ASSERTS must be either 0 or 1."
#endif
/* REDCONF_BLOCK_SIZE checked in redmacs.h
*/
#if (REDCONF_VOLUME_COUNT < 1U) || (REDCONF_VOLUME_COUNT > 255U)
#error "REDCONF_VOLUME_COUNT must be an integer between 1 and 255"
#endif
/* REDCONF_BUFFER_COUNT lower limit checked in buffer.c
*/
#if REDCONF_BUFFER_COUNT > 255U
#error "REDCONF_BUFFER_COUNT cannot be greater than 255"
#endif
#if (REDCONF_IMAGE_BUILDER != 0) && (REDCONF_IMAGE_BUILDER != 1)
#error "Configuration error: REDCONF_IMAGE_BUILDER must be either 0 or 1."
#endif
#if (REDCONF_CHECKER != 0) && (REDCONF_CHECKER != 1)
#error "Configuration error: REDCONF_CHECKER must be either 0 or 1."
#endif
#endif
@@ -0,0 +1,97 @@
/* ----> 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
*/
#ifndef REDCOREAPI_H
#define REDCOREAPI_H
#include <redstat.h>
REDSTATUS RedCoreInit(void);
REDSTATUS RedCoreUninit(void);
REDSTATUS RedCoreVolSetCurrent(uint8_t bVolNum);
#if FORMAT_SUPPORTED
REDSTATUS RedCoreVolFormat(void);
#endif
#if REDCONF_CHECKER == 1
REDSTATUS RedCoreVolCheck(void);
#endif
REDSTATUS RedCoreVolMount(void);
REDSTATUS RedCoreVolUnmount(void);
#if REDCONF_READ_ONLY == 0
REDSTATUS RedCoreVolTransact(void);
#endif
#if REDCONF_API_POSIX == 1
REDSTATUS RedCoreVolStat(REDSTATFS *pStatFS);
#endif
#if (REDCONF_READ_ONLY == 0) && ((REDCONF_API_POSIX == 1) || (REDCONF_API_FSE_TRANSMASKSET == 1))
REDSTATUS RedCoreTransMaskSet(uint32_t ulEventMask);
#endif
#if (REDCONF_API_POSIX == 1) || (REDCONF_API_FSE_TRANSMASKGET == 1)
REDSTATUS RedCoreTransMaskGet(uint32_t *pulEventMask);
#endif
#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX == 1)
REDSTATUS RedCoreCreate(uint32_t ulPInode, const char *pszName, bool fDir, uint32_t *pulInode);
#endif
#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX == 1) && (REDCONF_API_POSIX_LINK == 1)
REDSTATUS RedCoreLink(uint32_t ulPInode, const char *pszName, uint32_t ulInode);
#endif
#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX == 1) && ((REDCONF_API_POSIX_UNLINK == 1) || (REDCONF_API_POSIX_RMDIR == 1))
REDSTATUS RedCoreUnlink(uint32_t ulPInode, const char *pszName);
#endif
#if REDCONF_API_POSIX == 1
REDSTATUS RedCoreLookup(uint32_t ulPInode, const char *pszName, uint32_t *pulInode);
#endif
#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX == 1) && (REDCONF_API_POSIX_RENAME == 1)
REDSTATUS RedCoreRename(uint32_t ulSrcPInode, const char *pszSrcName, uint32_t ulDstPInode, const char *pszDstName);
#endif
#if REDCONF_API_POSIX == 1
REDSTATUS RedCoreStat(uint32_t ulInode, REDSTAT *pStat);
#endif
#if REDCONF_API_FSE == 1
REDSTATUS RedCoreFileSizeGet(uint32_t ulInode, uint64_t *pullSize);
#endif
REDSTATUS RedCoreFileRead(uint32_t ulInode, uint64_t ullStart, uint32_t *pulLen, void *pBuffer);
#if REDCONF_READ_ONLY == 0
REDSTATUS RedCoreFileWrite(uint32_t ulInode, uint64_t ullStart, uint32_t *pulLen, const void *pBuffer);
#endif
#if TRUNCATE_SUPPORTED
REDSTATUS RedCoreFileTruncate(uint32_t ulInode, uint64_t ullSize);
#endif
#if (REDCONF_API_POSIX == 1) && (REDCONF_API_POSIX_READDIR == 1)
REDSTATUS RedCoreDirRead(uint32_t ulInode, uint32_t *pulPos, char *pszName, uint32_t *pulInode);
#endif
#endif
@@ -0,0 +1,224 @@
/* ----> 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 This header contains macros which deviate from MISRA C:2012
*/
#ifndef REDDEVIATIONS_H
#define REDDEVIATIONS_H
/** @brief Append a suffix to a constant so that it is an unsigned 64-bit value.
Usages of this macro deviate from MISRA C:2012 Rule 1.2 (advisory). The
rule prohibits the use of language extensions. The ULL suffix became part
of the C standard with C99. Since this code base adheres to C89, use of
this suffix is a language extension. Reliance Edge needs to deal with
64-bit quantities, which by convention are explicitly suffixed. In at
least one case, with the INODE_SIZE_MAX macro, the code needs a way to force
a constant to be 64-bits even though its value is not so large that it would
be automatically promoted to 64-bits. Thus the need for this macro and the
deviation. In practice, the ULL suffix has proven to be a nearly universal
extension among C89 compilers.
As rule 19.2 is advisory, a deviation record is not required. This notice
is the only record of the deviation. PC-Lint does not issue an error for
this deviation so there is no error inhibition option.
Usages of this macro also deviate from MISRA C:2012 Rule 20.10 (advisory).
The rule prohibits use of the ## preprocessor operator. The code is not
obscure, and the operator is used only once, so this is deemed to be safe.
As rule 20.10 is advisory, a deviation record is not required. This notice
is the only record of the deviation.
Consistent use of this macro, even in non MISRA C code, is encouraged to
make it easier to search for 64-bit values.
*/
#define UINT64_SUFFIX(number) (number##ULL)
/** @brief Append a suffix to a constant so that it is a signed 64-bit value.
Usages of this macro deviate from MISRA C:2012 Rule 1.2 (advisory). See the
description of UINT64_SUFFIX() for details.
Usages of this macro deviate from MISRA C:2012 Rule 20.10 (advisory). See
the description of UINT64_SUFFIX() for details.
*/
#define INT64_SUFFIX(number) (number##LL)
/** @brief Cast a pointer to a const uint8_t pointer.
All usages of this macro deviate from MISRA C:2012 Rule 11.5 (advisory).
Because there are no alignment requirements for a uint8_t pointer, this is
safe. However, it is technically a deviation from the rule.
As Rule 11.5 is advisory, a deviation record is not required. This notice
and the PC-Lint error inhibition option are the only records of the
deviation.
*/
#define CAST_VOID_PTR_TO_CONST_UINT8_PTR(PTR) ((const uint8_t *)(PTR))
/** @brief Cast a pointer to a uint8_t pointer.
All usages of this macro deviate from MISRA C:2012 Rule 11.5 (advisory).
Because there are no alignment requirements for a uint8_t pointer, this is
safe. However, it is technically a deviation from the rule.
As Rule 11.5 is advisory, a deviation record is not required. This notice
and the PC-Lint error inhibition option are the only records of the
deviation.
*/
#define CAST_VOID_PTR_TO_UINT8_PTR(PTR) ((uint8_t *)(PTR))
/** @brief Cast a pointer to a const uint32_t pointer.
Usages of this macro may deviate from MISRA C:2012 Rule 11.5 (advisory).
It is only used in cases where the pointer is known to be aligned, and thus
it is safe to do so.
As Rule 11.5 is advisory, a deviation record is not required. This notice
and the PC-Lint error inhibition option are the only records of the
deviation.
Usages of this macro may deviate from MISRA C:2012 Rule 11.3 (required).
As Rule 11.3 is required, a separate deviation record is required.
Regarding the cast to (const void *): this is there to placate some
compilers which emit warnings when a type with lower alignment requirements
(such as const uint8_t *) is cast to a type with higher alignment
requirements. In the places where this macro is used, the pointer is
checked to be of sufficient alignment.
*/
#define CAST_CONST_UINT32_PTR(PTR) ((const uint32_t *)(const void *)(PTR))
/** @brief Cast a pointer to a pointer to (void **).
Usages of this macro deviate from MISRA C:2012 Rule 11.3 (required).
It is only used for populating a node structure pointer with a buffer
pointer. Buffer pointers are 8-byte aligned, thus it is safe to do so.
As Rule 11.3 is required, a separate deviation record is required.
*/
#define CAST_VOID_PTR_PTR(PTRPTR) ((void **)(PTRPTR))
/** @brief Create a two-dimensional byte array which is safely aligned.
Usages of this macro deviate from MISRA C:2012 Rule 19.2 (advisory).
A union is required to force alignment of the block buffers, which are used
to access metadata nodes, which must be safely aligned for 64-bit types.
As rule 19.2 is advisory, a deviation record is not required. This notice
and the PC-Lint error inhibition option are the only records of the
deviation.
*/
#define ALIGNED_2D_BYTE_ARRAY(un, nam, size1, size2) \
union \
{ \
uint8_t nam[size1][size2]; \
uint64_t DummyAlign; \
} un
/** @brief Determine whether RedMemMove() must copy memory in the forward
direction, instead of in the reverse.
In order to copy between overlapping memory regions, RedMemMove() must copy
forward if the destination memory is lower, and backward if the destination
memory is higher. Failure to do so would yield incorrect results.
The only way to make this determination without gross inefficiency is to
use pointer comparison. Pointer comparisons are undefined unless both
pointers point within the same object or array (or one element past the end
of the array); see section 6.3.8 of ANSI C89. While RedMemMove() is
normally only used when memory regions overlap, which would not result in
undefined behavior, it (like memmove()) is supposed to work even for non-
overlapping regions, which would make this function invoke undefined
behavior. Experience has shown the pointer comparisons of this sort behave
intuitively on common platforms, even though the behavior is undefined. For
those platforms where this is not the case, this implementation of memmove()
should be replaced with an alternate one.
Usages of this macro deviate from MISRA-C:2012 Rule 18.3 (required). As
Rule 18.3 is required, a separate deviation record is required.
*/
#define MEMMOVE_MUST_COPY_FORWARD(dest, src) ((dest) < (src))
/** @brief Cast a pointer to a (const DIRENT *).
Usages of this macro deviate from MISRA-C:2012 Rule 11.3 (required).
It is used for populating a directory entry structure pointer with a
buffer pointer. Buffer pointers are 8-byte aligned, and DIRENT only
requires 4-byte alignment, thus the typecast is safe.
As Rule 11.3 is required, a separate deviation record is required.
*/
#define CAST_CONST_DIRENT_PTR(PTR) ((const DIRENT *)(PTR))
/** @brief Determine whether a pointer is aligned.
A pointer is aligned if its address is an even multiple of
::REDCONF_ALIGNMENT_SIZE.
This is used in the slice-by-8 RedCrc32Update() function, which needs to
know whether a pointer is aligned, since the slice-by-8 algorithm needs to
access the memory in an aligned fashion, and if the pointer is not aligned,
this can result in faults or suboptimal performance (depending on platform).
There is no way to perform this check without deviating from MISRA C rules
against casting pointers to integer types. Usage of this macro deviates
from MISRA C:2012 Rule 11.4 (advisory). The main rationale the rule cites
against converting pointers to integers is that the chosen integer type may
not be able to represent the pointer; this is a non-issue here since we use
uintptr_t. The text says the rule still applies when using uintptr_t due to
concern about unaligned pointers, but that is not an issue here since the
integer value of the pointer is not saved and not converted back into a
pointer and dereferenced. The result of casting a pointer to a sufficiently
large integer is implementation-defined, but macros similar to this one have
been used by Datalight for a long time in a wide variety of environments and
they have always worked as expected.
As Rule 11.4 is advisory, a deviation record is not required. This notice
and the PC-Lint error inhibition option are the only records of the
deviation.
@note PC-Lint also thinks this macro as it is used below violates Rule 11.6
(required). This is a false positive, since Rule 11.6 only applies to
void pointers. Below, we use it on a pointer-to-object (uint8_t *),
which is covered by Rule 11.4.
*/
#define IS_ALIGNED_PTR(ptr) (((uintptr_t)(ptr) & (REDCONF_ALIGNMENT_SIZE - 1U)) == 0U)
#endif
@@ -0,0 +1,114 @@
/* ----> 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 Error values for Reliance Edge APIs
*/
#ifndef REDERRNO_H
#define REDERRNO_H
/** @brief Return type for Reliance Edge error values.
*/
typedef int32_t REDSTATUS;
/* The errno numbers are the same as Linux.
*/
/** Operation not permitted. */
#define RED_EPERM 1
/** No such file or directory. */
#define RED_ENOENT 2
/** I/O error. */
#define RED_EIO 5
/** Bad file number. */
#define RED_EBADF 9
/** Out of memory */
#define RED_ENOMEM 12
/** Device or resource busy. */
#define RED_EBUSY 16
/** File exists. */
#define RED_EEXIST 17
/** Cross-device link. */
#define RED_EXDEV 18
/** Not a directory. */
#define RED_ENOTDIR 20
/** Is a directory. */
#define RED_EISDIR 21
/** Invalid argument. */
#define RED_EINVAL 22
/** File table overflow. */
#define RED_ENFILE 23
/** Too many open files. */
#define RED_EMFILE 24
/** File too large. */
#define RED_EFBIG 27
/** No space left on device. */
#define RED_ENOSPC 28
/** Read-only file system. */
#define RED_EROFS 30
/** Too many links. */
#define RED_EMLINK 31
/** Math result not representable. */
#define RED_ERANGE 34
/** File name too long. */
#define RED_ENAMETOOLONG 36
/** Function not implemented. */
#define RED_ENOSYS 38
/** Directory not empty. */
#define RED_ENOTEMPTY 39
/** No data available. */
#define RED_ENODATA 61
/** Too many users. */
#define RED_EUSERS 87
/** Nothing will be okay ever again. */
#define RED_EFUBAR RED_EINVAL
#endif
@@ -0,0 +1,54 @@
/* ----> 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
*/
#ifndef REDEXCLUDE_H
#define REDEXCLUDE_H
#define DELETE_SUPPORTED \
( \
(REDCONF_READ_ONLY == 0) \
&& ( (REDCONF_API_POSIX == 1) \
&& ( (REDCONF_API_POSIX_RMDIR == 1) \
|| (REDCONF_API_POSIX_UNLINK == 1) \
|| ((REDCONF_API_POSIX_RENAME == 1) && (REDCONF_RENAME_ATOMIC == 1)))))
#define TRUNCATE_SUPPORTED \
( \
(REDCONF_READ_ONLY == 0) \
&& ( ((REDCONF_API_POSIX == 1) && (REDCONF_API_POSIX_FTRUNCATE == 1)) \
|| ((REDCONF_API_FSE == 1) && (REDCONF_API_FSE_TRUNCATE == 1))))
#define FORMAT_SUPPORTED \
( \
(REDCONF_READ_ONLY == 0) \
&& ( ((REDCONF_API_POSIX == 1) && (REDCONF_API_POSIX_FORMAT == 1)) \
|| ((REDCONF_API_FSE == 1) && (REDCONF_API_FSE_FORMAT == 1)) \
|| (REDCONF_IMAGE_BUILDER == 1)))
#endif
@@ -0,0 +1,46 @@
/* ----> 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
*/
#ifndef REDFS_H
#define REDFS_H
#include <redconf.h>
#include "redconfigchk.h"
#include <redtypes.h>
#include "rederrno.h"
#include "reddeviations.h"
#include "redmacs.h"
#include "redapimacs.h"
#include "redutils.h"
#include "redosserv.h"
#include "redmisc.h"
#include "redver.h"
#include "redexclude.h"
#endif
@@ -0,0 +1,105 @@
/* ----> 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 Interface for the Reliance Edge FSE API.
The FSE (File Systems Essentials) API is a minimalist file system API
intended for simple use cases with a fixed number of statically-defined
files. It does not support creating or deleting files dynamically. Files
are referenced by a fixed file number, rather than by name; there are no
file names and no directories. There are also no file handles: files are
not opened or closed, and file offsets are given explicitly.
If the FSE API is too limited to meet the needs of your application,
consider using the more feature-rich POSIX-like file system API instead.
*/
#ifndef REDFSE_H
#define REDFSE_H
/* This header is intended for application use; some applications are written
in C++.
*/
#ifdef __cplusplus
extern "C" {
#endif
#include <redconf.h>
#if REDCONF_API_FSE == 1
#include <redtypes.h>
#include "redapimacs.h"
#include "rederrno.h"
/** @brief First valid file number.
This macro can be used to statically define file numbers for given files,
as in the below example:
~~~{.c}
#define LOG_FILE (RED_FILENUM_FIRST_VALID)
#define DATABASE_FILE (RED_FILENUM_FIRST_VALID + 1U)
#define ICON1_FILE (RED_FILENUM_FIRST_VALID + 2U)
#define ICON2_FILE (RED_FILENUM_FIRST_VALID + 3U)
~~~
*/
#define RED_FILENUM_FIRST_VALID (2U)
REDSTATUS RedFseInit(void);
REDSTATUS RedFseUninit(void);
REDSTATUS RedFseMount(uint8_t bVolNum);
REDSTATUS RedFseUnmount(uint8_t bVolNum);
#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_FSE_FORMAT == 1)
REDSTATUS RedFseFormat(uint8_t bVolNum);
#endif
int32_t RedFseRead(uint8_t bVolNum, uint32_t ulFileNum, uint64_t ullFileOffset, uint32_t ulLength, void *pBuffer);
#if REDCONF_READ_ONLY == 0
int32_t RedFseWrite(uint8_t bVolNum, uint32_t ulFileNum, uint64_t ullFileOffset, uint32_t ulLength, const void *pBuffer);
#endif
#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_FSE_TRUNCATE == 1)
REDSTATUS RedFseTruncate(uint8_t bVolNum, uint32_t ulFileNum, uint64_t ullNewFileSize);
#endif
int64_t RedFseSizeGet(uint8_t bVolNum, uint32_t ulFileNum);
#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_FSE_TRANSMASKSET == 1)
REDSTATUS RedFseTransMaskSet(uint8_t bVolNum, uint32_t ulEventMask);
#endif
#if REDCONF_API_FSE_TRANSMASKGET == 1
REDSTATUS RedFseTransMaskGet(uint8_t bVolNum, uint32_t *pulEventMask);
#endif
#if REDCONF_READ_ONLY == 0
REDSTATUS RedFseTransact(uint8_t bVolNum);
#endif
#endif /* REDCONF_API_FSE == 1 */
#ifdef __cplusplus
}
#endif
#endif
@@ -0,0 +1,77 @@
/*-
* Copyright (c) 2000 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Dieter Baron and Thomas Klausner.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/** @file
@brief Interfaces for getopt() and getopt_long() work-alike functions.
This code was taken from FreeBSD and slightly modified, mostly to rename
symbols with external linkage to avoid naming conflicts in systems where
there are real getopt()/getopt_long() implementations. Changed to use
fixed-width types to allow code using these interfaces to be consistent
with the rest of the product.
*/
#ifndef REDGETOPT_H
#define REDGETOPT_H
#define red_no_argument 0
#define red_required_argument 1
#define red_optional_argument 2
/** @brief Specifies a long option.
*/
typedef struct
{
/* name of long option */
const char *name;
/*
* one of red_no_argument, red_required_argument, and red_optional_argument:
* whether option takes an argument
*/
int32_t has_arg;
/* if not NULL, set *flag to val when option found */
int32_t *flag;
/* if flag not NULL, value to set *flag to; else return value */
int32_t val;
} REDOPTION;
int32_t RedGetopt(int32_t nargc, char * const *nargv, const char *options);
int32_t RedGetoptLong(int32_t nargc, char * const *nargv, const char *options, const REDOPTION *long_options, int32_t *idx);
extern const char *red_optarg;
extern int32_t red_optind;
extern int32_t red_opterr;
extern int32_t red_optopt;
extern int32_t red_optreset;
#endif
@@ -0,0 +1,103 @@
/* ----> 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
*/
#ifndef REDMACS_H
#define REDMACS_H
#ifndef NULL
#define NULL ((void *)0)
#endif
#ifndef UINT8_MAX
#define UINT8_MAX (0xFFU)
#endif
#ifndef UINT16_MAX
#define UINT16_MAX (0xFFFFU)
#endif
#ifndef UINT32_MAX
#define UINT32_MAX (0xFFFFFFFFU)
#endif
#ifndef UINT64_MAX
#define UINT64_MAX UINT64_SUFFIX(0xFFFFFFFFFFFFFFFF)
#endif
#ifndef INT32_MAX
#define INT32_MAX (0x7FFFFFFF)
#endif
#ifndef INT64_MAX
#define INT64_MAX INT64_SUFFIX(0x7FFFFFFFFFFFFFFF)
#endif
#ifndef true
#define true (1)
#endif
#ifndef false
#define false (0)
#endif
#define SECTOR_SIZE_MIN (256U)
#if REDCONF_BLOCK_SIZE == 256U
#define BLOCK_SIZE_P2 8U
#elif REDCONF_BLOCK_SIZE == 512U
#define BLOCK_SIZE_P2 9U
#elif REDCONF_BLOCK_SIZE == 1024U
#define BLOCK_SIZE_P2 10U
#elif REDCONF_BLOCK_SIZE == 2048U
#define BLOCK_SIZE_P2 11U
#elif REDCONF_BLOCK_SIZE == 4096U
#define BLOCK_SIZE_P2 12U
#elif REDCONF_BLOCK_SIZE == 8192U
#define BLOCK_SIZE_P2 13U
#elif REDCONF_BLOCK_SIZE == 16384U
#define BLOCK_SIZE_P2 14U
#elif REDCONF_BLOCK_SIZE == 32768U
#define BLOCK_SIZE_P2 15U
#elif REDCONF_BLOCK_SIZE == 65536U
#define BLOCK_SIZE_P2 16U
#else
#error "REDCONF_BLOCK_SIZE must be a power of two value between 256 and 65536"
#endif
#define REDMIN(a, b) (((a) < (b)) ? (a) : (b))
#define INODE_INVALID (0U) /* General-purpose invalid inode number (must be zero). */
#define INODE_FIRST_VALID (2U) /* First valid inode number. */
#define INODE_ROOTDIR (INODE_FIRST_VALID) /* Inode number of the root directory. */
/* Expands to a "const" qualifier when the volume count is one, otherwise
expands to nothing. This is useful for variables that never change in
single-volume configurations but do change in multi-volume configurations.
*/
#if REDCONF_VOLUME_COUNT == 1U
#define CONST_IF_ONE_VOLUME const
#else
#define CONST_IF_ONE_VOLUME
#endif
#endif
@@ -0,0 +1,48 @@
/* ----> 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
*/
#ifndef REDMISC_H
#define REDMISC_H
/** @brief Type of an inode or handle.
Used to indicate the actual or expected type of an inode or handle.
*/
typedef enum
{
FTYPE_FILE, /**< Type is file. */
FTYPE_DIR, /**< Type is directory. */
/** Type is either file or directory: used only to indicate an expected
type, never as an actual type.
*/
FTYPE_EITHER
} FTYPE;
#endif
@@ -0,0 +1,86 @@
/* ----> 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
*/
#ifndef REDOSSERV_H
#define REDOSSERV_H
#include <redostypes.h>
/** @brief Type of access requested when opening a block device.
*/
typedef enum
{
BDEV_O_RDONLY, /**< Open block device for read access. */
BDEV_O_WRONLY, /**< Open block device for write access. */
BDEV_O_RDWR /**< Open block device for read and write access. */
} BDEVOPENMODE;
REDSTATUS RedOsBDevOpen(uint8_t bVolNum, BDEVOPENMODE mode);
REDSTATUS RedOsBDevClose(uint8_t bVolNum);
REDSTATUS RedOsBDevRead(uint8_t bVolNum, uint64_t ullSectorStart, uint32_t ulSectorCount, void *pBuffer);
#if REDCONF_READ_ONLY == 0
REDSTATUS RedOsBDevWrite(uint8_t bVolNum, uint64_t ullSectorStart, uint32_t ulSectorCount, const void *pBuffer);
REDSTATUS RedOsBDevFlush(uint8_t bVolNum);
#endif
/* Non-standard API: for host machines only.
*/
REDSTATUS RedOsBDevConfig(uint8_t bVolNum, const char *pszBDevSpec);
#if REDCONF_TASK_COUNT > 1U
REDSTATUS RedOsMutexInit(void);
REDSTATUS RedOsMutexUninit(void);
void RedOsMutexAcquire(void);
void RedOsMutexRelease(void);
#endif
#if (REDCONF_TASK_COUNT > 1U) && (REDCONF_API_POSIX == 1)
uint32_t RedOsTaskId(void);
#endif
REDSTATUS RedOsClockInit(void);
REDSTATUS RedOsClockUninit(void);
uint32_t RedOsClockGetTime(void);
REDSTATUS RedOsTimestampInit(void);
REDSTATUS RedOsTimestampUninit(void);
REDTIMESTAMP RedOsTimestamp(void);
uint64_t RedOsTimePassed(REDTIMESTAMP tsSince);
#if REDCONF_OUTPUT == 1
void RedOsOutputString(const char *pszString);
#endif
#if REDCONF_ASSERTS == 1
void RedOsAssertFail(const char *pszFileName, uint32_t ulLineNum);
#endif
#endif
@@ -0,0 +1,196 @@
/* ----> 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 Interface for the Reliance Edge POSIX-like API.
The POSIX-like file system API is the primary file system API for
Reliance Edge, which supports the full functionality of the file system.
This API aims to be compatible with POSIX where reasonable, but it is
simplified considerably to meet the needs of resource-constrained embedded
systems. The API has also been extended to provide access to the unique
features of Reliance Edge, and to cover areas (like mountins and formatting)
which do not have APIs in the POSIX specification.
*/
#ifndef REDPOSIX_H
#define REDPOSIX_H
/* This header is intended for application use; some applications are written
in C++.
*/
#ifdef __cplusplus
extern "C" {
#endif
#include <redconf.h>
#if REDCONF_API_POSIX == 1
#include <redtypes.h>
#include "redapimacs.h"
#include "rederrno.h"
#include "redstat.h"
/** Open for reading only. */
#define RED_O_RDONLY 0x00000001U
/** Open for writing only. */
#define RED_O_WRONLY 0x00000002U
/** Open for reading and writing. */
#define RED_O_RDWR 0x00000004U
/** File offset for all writes is end-of-file. */
#define RED_O_APPEND 0x00000008U
/** Create the file. */
#define RED_O_CREAT 0x00000010U
/** Error if path already exists. */
#define RED_O_EXCL 0x00000020U
/** Truncate file to size zero. */
#define RED_O_TRUNC 0x00000040U
/** @brief Last file system error (errno).
Under normal circumstances, each task using the file system has an
independent `red_errno` value. Applications do not need to worry about
one task obliterating an error value that another task needed to read. The
value is initially zero. When one of the POSIX-like APIs return an
indication of error, `red_errno` is set to an error value.
In some circumstances, `red_errno` will be a global errno location which
is shared by multiple tasks. If the calling task is not registered as a
file system user and all of the task slots are full, there can be no
task-specific errno, so the global errno is used. Likewise, if the file
system driver is uninitialized, there are no registered file system users
and `red_errno` always refers to the global errno. Under these
circumstances, multiple tasks manipulating `red_errno` could be
problematic. When the task count is set to one, `red_errno` always refers
to the global errno.
Note that `red_errno` is usable as an lvalue; i.e., in addition to reading
the error value, the error value can be set:
~~~{.c}
red_errno = 0;
~~~
*/
#define red_errno (*red_errnoptr())
/** @brief Positions from which to seek within a file.
*/
typedef enum
{
/* 0/1/2 are the traditional values for SET/CUR/END, respectively. Prior
to the release of Unix System V in 1983, the SEEK_* symbols did not
exist and C programs hard-coded the 0/1/2 values with those meanings.
*/
RED_SEEK_SET = 0, /**< Set file offset to given offset. */
RED_SEEK_CUR = 1, /**< Set file offset to current offset plus signed offset. */
RED_SEEK_END = 2 /**< Set file offset to EOF plus signed offset. */
} REDWHENCE;
#if REDCONF_API_POSIX_READDIR == 1
/** @brief Opaque directory handle.
*/
typedef struct sREDHANDLE REDDIR;
/** @brief Directory entry information.
*/
typedef struct
{
uint32_t d_ino; /**< File serial number (inode number). */
char d_name[REDCONF_NAME_MAX+1U]; /**< Name of entry. */
REDSTAT d_stat; /**< File information (POSIX extension). */
} REDDIRENT;
#endif
int32_t red_init(void);
int32_t red_uninit(void);
int32_t red_mount(const char *pszVolume);
int32_t red_umount(const char *pszVolume);
#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX_FORMAT == 1)
int32_t red_format(const char *pszVolume);
#endif
#if REDCONF_READ_ONLY == 0
int32_t red_transact(const char *pszVolume);
#endif
#if REDCONF_READ_ONLY == 0
int32_t red_settransmask(const char *pszVolume, uint32_t ulEventMask);
#endif
int32_t red_gettransmask(const char *pszVolume, uint32_t *pulEventMask);
int32_t red_statvfs(const char *pszVolume, REDSTATFS *pStatvfs);
int32_t red_open(const char *pszPath, uint32_t ulOpenMode);
#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX_UNLINK == 1)
int32_t red_unlink(const char *pszPath);
#endif
#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX_MKDIR == 1)
int32_t red_mkdir(const char *pszPath);
#endif
#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX_RMDIR == 1)
int32_t red_rmdir(const char *pszPath);
#endif
#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX_RENAME == 1)
int32_t red_rename(const char *pszOldPath, const char *pszNewPath);
#endif
#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX_LINK == 1)
int32_t red_link(const char *pszPath, const char *pszHardLink);
#endif
int32_t red_close(int32_t iFildes);
int32_t red_read(int32_t iFildes, void *pBuffer, uint32_t ulLength);
#if REDCONF_READ_ONLY == 0
int32_t red_write(int32_t iFildes, const void *pBuffer, uint32_t ulLength);
#endif
#if REDCONF_READ_ONLY == 0
int32_t red_fsync(int32_t iFildes);
#endif
int64_t red_lseek(int32_t iFildes, int64_t llOffset, REDWHENCE whence);
#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX_FTRUNCATE == 1)
int32_t red_ftruncate(int32_t iFildes, uint64_t ullSize);
#endif
int32_t red_fstat(int32_t iFildes, REDSTAT *pStat);
#if REDCONF_API_POSIX_READDIR == 1
REDDIR *red_opendir(const char *pszPath);
REDDIRENT *red_readdir(REDDIR *pDirStream);
void red_rewinddir(REDDIR *pDirStream);
int32_t red_closedir(REDDIR *pDirStream);
#endif
REDSTATUS *red_errnoptr(void);
#endif /* REDCONF_API_POSIX */
#ifdef __cplusplus
}
#endif
#endif
@@ -0,0 +1,94 @@
/* ----> 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
*/
#ifndef REDSTAT_H
#define REDSTAT_H
/** Mode bit for a directory. */
#define RED_S_IFDIR 0x4000U
/** Mode bit for a regular file. */
#define RED_S_IFREG 0x8000U
/** @brief Test for a directory.
*/
#define RED_S_ISDIR(m) (((m) & RED_S_IFDIR) != 0U)
/** @brief Test for a regular file.
*/
#define RED_S_ISREG(m) (((m) & RED_S_IFREG) != 0U)
/** File system is read-only. */
#define RED_ST_RDONLY 0x00000001U
/** File system ignores suid and sgid bits. */
#define RED_ST_NOSUID 0x00000002U
/** @brief Status information on an inode.
*/
typedef struct
{
uint8_t st_dev; /**< Volume number of volume containing file. */
uint32_t st_ino; /**< File serial number (inode number). */
uint16_t st_mode; /**< Mode of file. */
uint16_t st_nlink; /**< Number of hard links to the file. */
uint64_t st_size; /**< File size in bytes. */
#if REDCONF_INODE_TIMESTAMPS == 1
uint32_t st_atime; /**< Time of last access (seconds since 01-01-1970). */
uint32_t st_mtime; /**< Time of last data modification (seconds since 01-01-1970). */
uint32_t st_ctime; /**< Time of last status change (seconds since 01-01-1970). */
#endif
#if REDCONF_INODE_BLOCKS == 1
uint32_t st_blocks; /**< Number of blocks allocated for this object. */
#endif
} REDSTAT;
/** @brief Status information on a file system volume.
*/
typedef struct
{
uint32_t f_bsize; /**< File system block size. */
uint32_t f_frsize; /**< Fundamental file system block size. */
uint32_t f_blocks; /**< Total number of blocks on file system in units of f_frsize. */
uint32_t f_bfree; /**< Total number of free blocks. */
uint32_t f_bavail; /**< Number of free blocks available to non-privileged process. */
uint32_t f_files; /**< Total number of file serial numbers. */
uint32_t f_ffree; /**< Total number of free file serial numbers. */
uint32_t f_favail; /**< Number of file serial numbers available to non-privileged process. */
uint32_t f_fsid; /**< File system ID (useless, populated with zero). */
uint32_t f_flag; /**< Bit mask of f_flag values. Includes read-only file system flag. */
uint32_t f_namemax; /**< Maximum filename length. */
uint64_t f_maxfsize; /**< Maximum file size (POSIX extension). */
uint32_t f_dev; /**< Volume number (POSIX extension). */
} REDSTATFS;
#endif
@@ -0,0 +1,249 @@
/* ----> 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 Prototypes for Reliance Edge test entry points.
*/
#ifndef REDTESTS_H
#define REDTESTS_H
#include <redtypes.h>
#include "redtestutils.h"
#include "redver.h"
/* This macro is only defined by the error injection project.
*/
#ifdef REDCONF_ERROR_INJECTION
#include <rederrinject.h>
#endif
#define FSSTRESS_SUPPORTED \
( ((RED_KIT == RED_KIT_GPL) || (RED_KIT == RED_KIT_SANDBOX)) \
&& (REDCONF_OUTPUT == 1) && (REDCONF_READ_ONLY == 0) && (REDCONF_PATH_SEPARATOR == '/') \
&& (REDCONF_API_POSIX == 1) && (REDCONF_API_POSIX_UNLINK == 1) && (REDCONF_API_POSIX_MKDIR == 1) \
&& (REDCONF_API_POSIX_RMDIR == 1) && (REDCONF_API_POSIX_RENAME == 1) && (REDCONF_API_POSIX_LINK == 1) \
&& (REDCONF_API_POSIX_FTRUNCATE == 1) && (REDCONF_API_POSIX_READDIR == 1))
#define FSE_STRESS_TEST_SUPPORTED \
( ((RED_KIT == RED_KIT_COMMERCIAL) || (RED_KIT == RED_KIT_SANDBOX)) \
&& (REDCONF_OUTPUT == 1) && (REDCONF_READ_ONLY == 0) && (REDCONF_API_FSE == 1) \
&& (REDCONF_API_FSE_FORMAT == 1) && (REDCONF_API_FSE_TRANSMASKSET == 1) && (REDCONF_API_FSE_TRANSMASKGET == 1) \
&& (REDCONF_API_FSE_TRUNCATE == 1))
#define POSIX_API_TEST_SUPPORTED \
( ((RED_KIT == RED_KIT_COMMERCIAL) || (RED_KIT == RED_KIT_SANDBOX)) \
&& (REDCONF_OUTPUT == 1) && (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX == 1) \
&& (REDCONF_API_POSIX_FORMAT == 1) && (REDCONF_API_POSIX_UNLINK == 1))
#define FSE_API_TEST_SUPPORTED \
( ((RED_KIT == RED_KIT_COMMERCIAL) || (RED_KIT == RED_KIT_SANDBOX)) \
&& (REDCONF_OUTPUT == 1) && (REDCONF_READ_ONLY == 0) && (REDCONF_API_FSE == 1) \
&& (REDCONF_API_FSE_FORMAT == 1))
#define STOCH_POSIX_TEST_SUPPORTED \
( ((RED_KIT == RED_KIT_COMMERCIAL) || (RED_KIT == RED_KIT_SANDBOX)) \
&& (REDCONF_OUTPUT == 1) && (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX == 1) \
&& (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX_FORMAT == 1) && (REDCONF_API_POSIX_READDIR == 1) \
&& (REDCONF_API_POSIX_MKDIR == 1) && (REDCONF_API_POSIX_RMDIR == 1) && (REDCONF_API_POSIX_UNLINK == 1) \
&& (REDCONF_API_POSIX_RENAME == 1))
#define FSIOTEST_SUPPORTED \
( ((RED_KIT == RED_KIT_COMMERCIAL) || (RED_KIT == RED_KIT_SANDBOX)) \
&& (REDCONF_OUTPUT == 1) && (REDCONF_API_POSIX == 1))
#define BDEVTEST_SUPPORTED \
( ((RED_KIT == RED_KIT_COMMERCIAL) || (RED_KIT == RED_KIT_SANDBOX)) \
&& (REDCONF_OUTPUT == 1) && (REDCONF_READ_ONLY == 0))
#define DISKFULL_TEST_SUPPORTED \
( ((RED_KIT == RED_KIT_COMMERCIAL) || (RED_KIT == RED_KIT_SANDBOX)) \
&& (REDCONF_OUTPUT == 1) && (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX == 1) \
&& (REDCONF_API_POSIX_FORMAT == 1) && (REDCONF_API_POSIX_FTRUNCATE == 1))
typedef enum
{
PARAMSTATUS_OK, /* Parameters were good; continue. */
PARAMSTATUS_BAD, /* Parameters were bad; stop. */
PARAMSTATUS_HELP /* Help request; not an error, but stop. */
} PARAMSTATUS;
#if FSSTRESS_SUPPORTED
typedef struct
{
bool fNoCleanup; /**< --no-cleanup */
uint32_t ulLoops; /**< --loops */
uint32_t ulNops; /**< --nops */
bool fNamePad; /**< --namepad */
uint32_t ulSeed; /**< --seed */
bool fVerbose; /**< --verbose */
} FSSTRESSPARAM;
PARAMSTATUS FsstressParseParams(int argc, char *argv[], FSSTRESSPARAM *pParam, uint8_t *pbVolNum, const char **ppszDevice);
void FsstressDefaultParams(FSSTRESSPARAM *pParam);
int FsstressStart(const FSSTRESSPARAM *pParam);
#endif
#if STOCH_POSIX_TEST_SUPPORTED
typedef struct
{
const char *pszVolume; /**< Volume path prefix. */
uint32_t ulIterations; /**< --iterations */
uint32_t ulFileListMax; /**< --files */
uint32_t ulDirListMax; /**< --dirs */
uint32_t ulOpenFileListMax; /**< --open-files */
uint32_t ulOpenDirListMax; /**< --open-dirs */
uint32_t ulRandomSeed; /**< --seed */
} STOCHPOSIXPARAM;
PARAMSTATUS RedStochPosixParseParams(int argc, char *argv[], STOCHPOSIXPARAM *pParam, uint8_t *pbVolNum, const char **ppszDevice);
void RedStochPosixDefaultParams(STOCHPOSIXPARAM *pParam);
int RedStochPosixStart(const STOCHPOSIXPARAM *pParam);
#endif
#if FSE_STRESS_TEST_SUPPORTED
typedef struct
{
uint8_t bVolNum; /**< Volume number. */
uint32_t ulFileCount; /**< --files */
uint32_t ulMaxFileSize; /**< --max */
uint32_t ulMaxOpSize; /**< --buffer-size */
uint32_t ulNops; /**< --nops */
uint32_t ulLoops; /**< --loops */
uint32_t ulSampleRate; /**< --sample-rate */
uint64_t ullSeed; /**< --seed */
} FSESTRESSPARAM;
PARAMSTATUS FseStressParseParams(int argc, char *argv[], FSESTRESSPARAM *pParam, uint8_t *pbVolNum, const char **ppszDevice);
void FseStressDefaultParams(FSESTRESSPARAM *pParam);
int FseStressStart(const FSESTRESSPARAM *pParam);
#endif
#if POSIX_API_TEST_SUPPORTED
typedef struct
{
const char *pszVolume; /**< Volume path prefix. */
bool fQuick; /**< --quick */
bool fQuitOnFailure; /**< --quit-on-failure */
bool fDebugErrors; /**< --debug */
} POSIXTESTPARAM;
PARAMSTATUS RedPosixTestParseParams(int argc, char *argv[], POSIXTESTPARAM *pParam, uint8_t *pbVolNum, const char **ppszDevice);
void RedPosixTestDefaultParams(POSIXTESTPARAM *pParam);
int RedPosixTestStart(const POSIXTESTPARAM *pParam);
#endif
#if FSE_API_TEST_SUPPORTED
typedef struct
{
uint8_t bVolNum; /**< Volume number. */
bool fQuitOnFailure; /**< --quit-on-failure */
bool fDebugErrors; /**< --debug */
} FSETESTPARAM;
PARAMSTATUS RedFseTestParseParams(int argc, char *argv[], FSETESTPARAM *pParam, uint8_t *pbVolNum, const char **ppszDevice);
void RedFseTestDefaultParams(FSETESTPARAM *pParam);
int RedFseTestStart(const FSETESTPARAM *pParam);
#endif
#if FSIOTEST_SUPPORTED
typedef enum
{
TESTFS_RELEDGE, /* Datalight Reliance Edge */
TESTFS_FATFS, /* ChaN's FatFs */
TESTFS_FATSL /* FreeRTOS+FAT SL */
} TESTFS;
typedef struct
{
TESTFS testfs; /**< --fs */
const char *pszVolume; /**< Volume path prefix. */
bool fSeqRead; /**< --seq=r */
bool fSeqWrite; /**< --seq=w */
bool fSeqRewrite; /**< --seq=e */
bool fRandomRead; /**< --rand=r */
bool fRandomWrite; /**< --rand=w */
bool fMixedWrite; /**< --mixed */
bool fScanTest; /**< --scan */
uint32_t ulFSBlockSize; /**< --block-size */
uint32_t ulMaxFileSize; /**< --max */
uint32_t ulRandomReadPasses; /**< --rand-pass=r:w (r part) */
uint32_t ulRandomWritePasses; /**< --rand-pass=r:w (w part) */
uint32_t ulMixedWritePasses; /**< --mixed-pass */
int32_t iFlushOnWriteRatio; /**< --rand-fow */
uint32_t ulBufferMin; /**< --start */
uint32_t ulBufferSize; /**< --buffer-size */
bool fWriteVerify; /**< --verify */
uint32_t ulSampleRate; /**< --sample-rate */
uint32_t ulScanCount; /**< --scan-files */
uint64_t ullSeed; /**< --seed */
} FSIOTESTPARAM;
PARAMSTATUS FSIOTestParseParams(int argc, char *argv[], FSIOTESTPARAM *pParam, uint8_t *pbVolNum, const char **ppszDevice);
void FSIOTestDefaultParams(FSIOTESTPARAM *pParam);
int FSIOTestStart(const FSIOTESTPARAM *pParam);
#endif
#if BDEVTEST_SUPPORTED
typedef struct
{
uint8_t bDrvNum; /**< Volume number (for sector size/count). */
bool fSeqWrite; /**< --seq:w */
bool fSeqRead; /**< --seq:r */
bool fRandWrite; /**< --rand:w */
bool fRandRead; /**< --rand:r */
uint32_t ulSampleSecs; /**< --sample-rate */
uint32_t ulPasses; /**< --passes */
uint32_t ulMinIOSectors; /**< --count=min[:max] (min part) */
uint32_t ulMaxIOSectors; /**< --count=min[:max] (max part) */
uint32_t ulMaxSizeKB; /**< --max */
uint32_t ulTestSeconds; /**< --time */
bool fVerify; /**< --verify */
bool fAsyncWrites; /**< --async */
uint64_t ullSeed; /**< --seed */
} BDEVTESTPARAM;
PARAMSTATUS BDevTestParseParams(int argc, char *argv[], BDEVTESTPARAM *pParam, uint8_t *pbVolNum, const char **ppszDevice);
void BDevTestDefaultParams(BDEVTESTPARAM *pParam);
int BDevTestStart(const BDEVTESTPARAM *pParam);
#endif
#if DISKFULL_TEST_SUPPORTED
typedef struct
{
const char *pszVolume; /**< Volume path prefix. */
bool fQuitOnFailure; /**< --quit-on-failure */
bool fDebugErrors; /**< --debug */
} DISKFULLTESTPARAM;
PARAMSTATUS DiskFullTestParseParams(int argc, char *argv[], DISKFULLTESTPARAM *pParam, uint8_t *pbVolNum, const char **ppszDevice);
void DiskFullTestDefaultParams(DISKFULLTESTPARAM *pParam);
int DiskFullTestStart(const DISKFULLTESTPARAM *pParam);
#endif
#endif
@@ -0,0 +1,71 @@
/* ----> 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 Reliance Edge utilities only needed for tests.
*/
#ifndef REDTESTUTILS_H
#define REDTESTUTILS_H
#define ISDIGIT(c) (((c) >= '0') && ((c) <= '9'))
void RedRandSeed(uint64_t ullSeed);
uint64_t RedRand64(uint64_t *pullSeed);
uint32_t RedRand32(uint32_t *pulSeed);
char *RedRatio(char *pBuffer, uint32_t ulBufferLen, uint64_t ullDividend, uint64_t ullDivisor, uint32_t ulDecPlaces);
uint64_t RedMulDiv64(uint64_t ullBase, uint32_t ulMultiplier, uint64_t ullDivisor);
uint64_t RedUint64DivMod32(uint64_t ullDividend, uint32_t ulDivisor, uint32_t *pulRemainder);
uint64_t RedUint64DivMod64(uint64_t ullDividend, uint64_t ullDivisor, uint64_t *pullRemainder);
char *RedScaleBytes(uint32_t ulByteValue, char *pszBuffer, uint32_t ulBufferSize);
char *RedScaleKB(uint32_t ulKBValue, char *pszBuffer, uint32_t ulBufferSize);
uint32_t RedGetKBPerSecond(uint64_t ullKB, uint32_t ulMS);
uint32_t RedGetKBPerSecondSectors(uint32_t ulBytesPerSector, uint64_t ullSectors, uint64_t ullUS);
int32_t RedAtoI(const char *pszNum);
const char *RedHtoUL(const char *pszNum, uint32_t *pulNum);
const char *RedHtoULL(const char *pszNum, uint64_t *pullNum);
const char *RedNtoUL(const char *pszNum, uint32_t *pulNum);
const char *RedNtoULL(const char *pszNum, uint64_t *pullNum);
const char *RedSizeToUL(const char *pszNum, uint32_t *pulResult);
int32_t RedStrICmp(const char *pszStr1, const char *pszStr2);
int32_t RedStrNICmp(const char *pszStr1, const char *pszStr2, uint32_t ulLen);
char RedToLower(char c);
#include <stdarg.h>
#if REDCONF_OUTPUT == 1
void RedPrintf(const char *pszFormat, ...);
void RedVPrintf(const char *pszFormat, va_list arglist);
#endif
int32_t RedSNPrintf(char *pcBuffer, uint32_t ulBufferLen, const char *pszFormat, ...);
int32_t RedVSNPrintf(char *pcBuffer, uint32_t ulBufferLen, const char *pszFormat, va_list arglist);
#endif
@@ -0,0 +1,36 @@
/* ----> 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 Interfaces for common-code utilities for tools and tests.
*/
#ifndef REDTOOLCMN_H
#define REDTOOLCMN_H
uint8_t RedFindVolumeNumber(const char *pszVolume);
#endif
@@ -0,0 +1,71 @@
/* ----> 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
*/
#ifndef REDUTILS_H
#define REDUTILS_H
#if REDCONF_ASSERTS == 1
#define REDERROR() RedOsAssertFail(__FILE__, __LINE__)
#define REDASSERT(EXP) ((EXP) ? (void)0 : REDERROR())
#else
#define REDERROR() ((void)0)
#define REDASSERT(EXP) ((void)0)
#endif
void RedMemCpy(void *pDest, const void *pSrc, uint32_t ulLen);
void RedMemMove(void *pDest, const void *pSrc, uint32_t ulLen);
void RedMemSet(void *pDest, uint8_t bVal, uint32_t ulLen);
int32_t RedMemCmp(const void *pMem1, const void *pMem2, uint32_t ulLen);
uint32_t RedStrLen(const char *pszStr);
int32_t RedStrCmp(const char *pszStr1, const char *pszStr2);
int32_t RedStrNCmp(const char *pszStr1, const char *pszStr2, uint32_t ulLen);
void RedStrNCpy(char *pszDst, const char *pszSrc, uint32_t ulLen);
uint32_t RedCrc32Update(uint32_t ulInitCrc32, const void *pBuffer, uint32_t ulLength);
uint32_t RedCrcNode(const void *pBuffer);
#if REDCONF_API_POSIX == 1
uint32_t RedNameLen(const char *pszName);
#endif
bool RedBitGet(const uint8_t *pbBitmap, uint32_t ulBit);
void RedBitSet(uint8_t *pbBitmap, uint32_t ulBit);
void RedBitClear(uint8_t *pbBitmap, uint32_t ulBit);
#ifdef REDCONF_ENDIAN_SWAP
uint64_t RedRev64(uint64_t ullToRev);
uint32_t RedRev32(uint32_t ulToRev);
uint16_t RedRev16(uint16_t uToRev);
#endif
void RedSignOn(void);
#endif
@@ -0,0 +1,106 @@
/* ----> 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 Macros for version numbers, build number, and product information.
*/
#ifndef REDVER_H
#define REDVER_H
/** @brief Consecutive number assigned to each automated build.
<!-- This macro is updated automatically: do not edit! -->
*/
#define RED_BUILD_NUMBER "664"
#define RED_KIT_GPL 0U /* Open source GPL kit. */
#define RED_KIT_COMMERCIAL 1U /* Commercially-licensed kit. */
#define RED_KIT_SANDBOX 2U /* Not a kit: developer sandbox. */
/** @brief Indicates the Reliance Edge kit.
<!-- This macro is updated automatically: do not edit! -->
*/
#define RED_KIT RED_KIT_GPL
/** @brief Version number to display in output.
*/
#define RED_VERSION "v1.0"
/** @brief On-disk version number.
This is incremented only when the on-disk layout is updated in such a way
which is incompatible with previously released versions of the file system.
*/
#define RED_DISK_LAYOUT_VERSION 1U
/** @brief Base name of the file system product.
*/
#define RED_PRODUCT_BASE_NAME "Reliance Edge"
/* Specifies whether the product is in alpha stage, beta stage, or neither.
*/
#if 0
#if 1
#define ALPHABETA " (Alpha)"
#else
#define ALPHABETA " (Beta)"
#endif
#else
#define ALPHABETA ""
#endif
/** @brief Full product name and version.
*/
#define RED_PRODUCT_NAME "Datalight "RED_PRODUCT_BASE_NAME" "RED_VERSION" Build "RED_BUILD_NUMBER ALPHABETA
/** @brief Product copyright.
*/
#define RED_PRODUCT_LEGAL "Copyright (c) 2014-2015 Datalight, Inc. All Rights Reserved Worldwide."
/** @brief Product patents.
*/
#define RED_PRODUCT_PATENT "Patents: US#7284101."
/** @brief Product edition.
*/
#if RED_KIT == RED_KIT_GPL
#define RED_PRODUCT_EDITION "Open-Source GPLv2 Edition -- Compiled "__DATE__" at "__TIME__
#elif RED_KIT == RED_KIT_COMMERCIAL
#define RED_PRODUCT_EDITION "Commercial Edition -- Compiled "__DATE__" at "__TIME__
#else
#define RED_PRODUCT_EDITION "Developer Sandbox -- Compiled "__DATE__" at "__TIME__
#endif
#endif
@@ -0,0 +1,134 @@
/* ----> 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
*/
#ifndef REDVOLUME_H
#define REDVOLUME_H
/** @brief Per-volume configuration structure.
Contains the configuration values that may differ between volumes. Must be
declared in an array in redconf.c in the Reliance Edge project directory and
statically initialized with values representing the volume configuration of
the target system.
*/
typedef struct
{
/** The sector size for the block device underlying the volume: the basic
unit for reading and writing to the storage media. Commonly ranges
between 512 and 4096, but any power-of-two value not greater than the
block size will work.
*/
uint32_t ulSectorSize;
/** The number of sectors in this file system volume.
*/
uint64_t ullSectorCount;
/** Whether a sector write on the block device underlying the volume is
atomic. It is atomic if when the sector write is interrupted, the
contents of the sector are guaranteed to be either all of the new data,
or all of the old data. If unsure, leave as false.
*/
bool fAtomicSectorWrite;
/** This is the maximum number of inodes (files and directories). This
number includes the root directory inode (inode 2; created during
format), but does not include inodes 0 or 1, which do not exist on
disk. The number of inodes cannot be less than 1.
*/
uint32_t ulInodeCount;
#if REDCONF_API_POSIX == 1
/** The path prefix for the volume; for example, "VOL1:", "FlashDisk", etc.
*/
const char *pszPathPrefix;
#endif
} VOLCONF;
extern const VOLCONF gaRedVolConf[REDCONF_VOLUME_COUNT];
extern const VOLCONF * CONST_IF_ONE_VOLUME gpRedVolConf;
/** @brief Per-volume run-time data.
*/
typedef struct
{
/** Whether the volume is currently mounted.
*/
bool fMounted;
#if REDCONF_READ_ONLY == 0
/** Whether the volume is read-only.
*/
bool fReadOnly;
/** The active automatic transaction mask.
*/
uint32_t ulTransMask;
#endif
/** The power of 2 difference between sector size and block size.
*/
uint8_t bBlockSectorShift;
/** The number of logical blocks in this file system volume. The unit here
is the global block size.
*/
uint32_t ulBlockCount;
/** The total number of allocable blocks; Also the maximum count of free
blocks.
*/
uint32_t ulBlocksAllocable;
/** The maximum number of bytes that an inode is capable of addressing.
*/
uint64_t ullMaxInodeSize;
/** The current metadata sequence number. This value is included in all
metadata nodes and incremented every time a metadata node is written.
It is assumed to never wrap around.
*/
uint64_t ullSequence;
} VOLUME;
/* Array of VOLUME structures, populated at during RedCoreInit().
*/
extern VOLUME gaRedVolume[REDCONF_VOLUME_COUNT];
/* Volume number currently being accessed; populated during
RedCoreVolSetCurrent().
*/
extern CONST_IF_ONE_VOLUME uint8_t gbRedVolNum;
/* Pointer to the volume currently being accessed; populated during
RedCoreVolSetCurrent().
*/
extern VOLUME * CONST_IF_ONE_VOLUME gpRedVolume;
#endif
@@ -0,0 +1,165 @@
/* ----> 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 Macros to encapsulate MISRA C:2012 deviations in OS-specific code.
*/
#ifndef REDOSDEVIATIONS_H
#define REDOSDEVIATIONS_H
#if REDCONF_OUTPUT == 1
/* Needed for PRINT_ASSERT() and OUTPUT_CHARACTER().
*/
#include <stdio.h>
#endif
#if REDCONF_ASSERTS == 1
#if REDCONF_OUTPUT == 1
/** Print a formatted message for an assertion.
Usages of this macro deviate from MISRA C:2012 Rule 21.6 (required). Using
printf() is the most convenient way to output this information; and the risk
of "unspecified, undefined and implementation-defined" behavior causing
problems (as cited in the rationale for the rule) is small. The driver does
not depend on this string being outputted correctly. Furthermore, use of
printf() disappears when either asserts or output are disabled.
As Rule 21.6 is required, a separate deviation record is required.
*/
#define PRINT_ASSERT(file, line) \
(void)printf("Assertion failed in \"%s\" at line %u\n\r", ((file) == NULL) ? "" : (file), (unsigned)(line))
#else
#define PRINT_ASSERT(file, line) do { (void)(file); (void)(line); } while(false)
#endif /* REDCONF_OUTPUT == 1 */
#endif /* REDCONF_ASSERTS == 1 */
/** Cast a value to unsigned long.
Usages of this macro deviate from MISRA C:2012 Directive 4.6. This macro is
used in two places to cast a uint64_t value (used by the block device
abstraction for sector numbers) to unsigned long, since third-party code
which is not under the control of this project uses unsigned long for sector
numbers. The cast is guaranteed to not lose any information, since when the
disk is opened the sector count is verified to be less than or equal to an
unsigned long value. The text of the directive mentions that "it might be
desirable not to apply this guideline when interfacing with ... code outside
the project's control", which describes the situation for this deviation.
As Directive 4.6 is advisory, a deviation record is not required. This
notice is the only record of the deviation.
*/
#define CAST_ULONG(ull) ((unsigned long)(ull))
/** Cast a const-qualified pointer to a pointer which is *not* const-qualified.
Usages of this macro deviate from MISRA C:2012 Rule 11.8. This macro is
used in exactly one place in order to cope with a poorly designed
third-party interface. Reliance Edge, at every level of the stack, uses
const-qualified pointers for buffers used in write operations, since the
data is read from the buffer, and the buffer does not need to be modified
(consistent with Rule 8.13). One of the third-party block device interfaces
that Reliance Edge interfaces with does not follow this convention: it uses
an unqualified pointer for the buffer parameter of its sector write
function. This forces the need for the cast to avoid warnings. The
implementation of the sector write function is provided by the user, so it
is to be hoped that the buffer is not actually modified.
As Rule 11.8 is required, a separate deviation record is required.
*/
#define CAST_AWAY_CONST(type, ptr) ((type *)(ptr))
/** Allocate zero-initialized (cleared) memory.
All usages of this macro deviate from MISRA C:2012 Directive 4.12 (required)
and Rule 21.3 (required). In the context of the single place it is actually
used, this macro also deviates from Rule 22.1 (required).
This macro is used in the FreeRTOS block device code in order to allocate a
RAM disk, when that implementation of the block device is selected. The
primary rationale for all these deviations is that a) the RAM disk cannot be
allocated statically (since the volume information is stored in a
structure), and b) the RAM disk is primarily intended as a temporary testing
tool for users who want to try out Reliance Edge before the real storage
media is available. In most real systems, Reliance Edge is used with
non-volatile storage like SD/MMC or eMMC, not with RAM disks.
Rule 22.1 states that all resources which are allocated must also be
explicitly freed. The RAM disk is allocated and never freed, deviating from
that rule. This is done because the data in the RAM disk is emulating a
non-volatile storage medium, and thus needs to persist even after the block
device is closed, to allow the file system to be ormatted and then mounted,
or unmounted and remounted in the course of a test. Thus the memory will
remain allocated until the target device is rebooted. This is assumed to be
acceptable for the primary purpose of the RAM disk, which is preliminary
testing.
As Directive 4.12, Rule 21.3, and Rule 22.1 are all required, separate
deviation records are required.
*/
#define ALLOCATE_CLEARED_MEMORY(nelem, elsize) calloc(nelem, elsize)
#if REDCONF_OUTPUT == 1
/** Output a character to a serial port or other display device.
Usages of this macro deviate from MISRA C:2012 Rule 21.6 (required).
FreeRTOS does not include a standard method of printing characters, so
putchar() is the most convenient and portable way to accomplish the task.
The risk of "unspecified, undefined and implementation-defined" behavior
causing problems (as cited in the rationale for the rule) is small. The
driver does not depend on the character being outputted correctly.
Furthermore, use of putchar() disappears when output is disabled.
As Rule 21.6 is required, a separate deviation record is required.
*/
#define OUTPUT_CHARACTER(ch) (void)putchar(ch)
#endif
#if (REDCONF_TASK_COUNT > 1U) && (REDCONF_API_POSIX == 1)
/** Cast a TaskHandle_t (a pointer type) to uintptr_t.
Usage of this macro deivate from MISRA-C:2012 Rule 11.4 (advisory). This
macro is used for the FreeRTOS version of RedOsTaskId(). Some RTOSes
natively use an integer for task IDs; others use pointers. RedOsTaskId()
uses integers, FreeRTOS uses pointers; to reconcile this difference, the
pointer must be cast to integer. This is fairly safe, since the resulting
integer is never cast back to a pointer; and although the integer
representation of a pointer is implementation-defined, the representation is
irrelevant provided that unique pointers are converted to unique integers.
As Rule 11.4 is advisory, a deviation record is not required. This notice
is the only record of the deviation.
*/
#define CAST_TASK_PTR_TO_UINTPTR(taskptr) ((uintptr_t)(taskptr))
#endif
#endif
@@ -0,0 +1,42 @@
/* ----> 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 Defines OS-specific types for use in common code.
*/
#ifndef REDOSTYPES_H
#define REDOSTYPES_H
/** @brief Implementation-defined timestamp type.
This can be an integer, a structure, or a pointer: anything that is
convenient for the implementation. Since the underlying type is not fixed,
common code should treat this as an opaque type.
*/
typedef uint32_t REDTIMESTAMP;
#endif
@@ -0,0 +1,54 @@
/* ----> 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 assertion handling.
*/
#include <redfs.h>
#if REDCONF_ASSERTS == 1
#include <redosdeviations.h>
/** @brief Invoke the native assertion handler.
@param pszFileName Null-terminated string containing the name of the file
where the assertion fired.
@param ulLineNum Line number in @p pszFileName where the assertion
fired.
*/
void RedOsAssertFail(
const char *pszFileName,
uint32_t ulLineNum)
{
PRINT_ASSERT(pszFileName, ulLineNum);
for( ;; )
{
}
}
#endif
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,79 @@
/* ----> 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 real-time clock functions.
*/
#include <redfs.h>
/** @brief Initialize the real time clock.
The behavior of calling this function when the RTC is already initialized
is undefined.
@return A negated ::REDSTATUS code indicating the operation result.
@retval 0 Operation was successful.
*/
REDSTATUS RedOsClockInit(void)
{
return 0;
}
/** @brief Uninitialize the real time clock.
The behavior of calling this function when the RTC is not initialized is
undefined.
@return A negated ::REDSTATUS code indicating the operation result.
@retval 0 Operation was successful.
*/
REDSTATUS RedOsClockUninit(void)
{
return 0;
}
/** @brief Get the date/time.
The behavior of calling this function when the RTC is not initialized is
undefined.
@return The number of seconds since January 1, 1970 excluding leap seconds
(in other words, standard Unix time). If the resolution or epoch
of the RTC is different than this, the implementation must convert
it to the expected representation.
*/
uint32_t RedOsClockGetTime(void)
{
/* FreeRTOS does not provide an RTC abstraction since most of the systems
it targets have no RTC hardware. If your hardware includes an RTC that
you would like to use, this function must be customized.
*/
return 0;
}
@@ -0,0 +1,120 @@
/* ----> 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 a synchronization object to provide mutual exclusion.
*/
#include <FreeRTOS.h>
#include <semphr.h>
#include <redfs.h>
#if REDCONF_TASK_COUNT > 1U
static SemaphoreHandle_t xMutex;
/** @brief Initialize the mutex.
After initialization, the mutex is in the released state.
The behavior of calling this function when the mutex is still initialized
is undefined.
@return A negated ::REDSTATUS code indicating the operation result.
@retval 0 Operation was successful.
*/
REDSTATUS RedOsMutexInit(void)
{
REDSTATUS ret;
xMutex = xSemaphoreCreateMutex();
if(xMutex != NULL)
{
ret = 0;
}
else
{
ret = -RED_ENOMEM;
}
return ret;
}
/** @brief Uninitialize the mutex.
The behavior of calling this function when the mutex is not initialized is
undefined; likewise, the behavior of uninitializing the mutex when it is
in the acquired state is undefined.
@return A negated ::REDSTATUS code indicating the operation result.
@retval 0 Operation was successful.
*/
REDSTATUS RedOsMutexUninit(void)
{
vSemaphoreDelete(xMutex);
xMutex = NULL;
return 0;
}
/** @brief Acquire the mutex.
The behavior of calling this function when the mutex is not initialized is
undefined; likewise, the behavior of recursively acquiring the mutex is
undefined.
*/
void RedOsMutexAcquire(void)
{
while(xSemaphoreTake(xMutex, portMAX_DELAY) != pdTRUE)
{
}
}
/** @brief Release the mutex.
The behavior is undefined in the following cases:
- Releasing the mutex when the mutex is not initialized.
- Releasing the mutex when it is not in the acquired state.
- Releasing the mutex from a task or thread other than the one which
acquired the mutex.
*/
void RedOsMutexRelease(void)
{
BaseType_t xSuccess;
xSuccess = xSemaphoreGive(xMutex);
REDASSERT(xSuccess == pdTRUE);
(void)xSuccess;
}
#endif

Some files were not shown because too many files have changed in this diff Show More