/*             ----> 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;

    /** This is the maximum number of times a block device I/O operation will
        be retried.  If a block device read, write, or flush fails, Reliance
        Edge will try again up to this number of times until the operation is
        successful.  Set this to 0 to disable retries.
    */
    uint8_t     bBlockIoRetries;

  #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

