daa3168cfb
Fixes the journal log read and write size and overlap issues, along with read return value issue. Signed-off-by: Saurav Pal <resyfer.dev@gmail.com>
1909 lines
57 KiB
C
1909 lines
57 KiB
C
/****************************************************************************
|
|
* fs/mnemofs/mnemofs.h
|
|
*
|
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
|
* contributor license agreements. See the NOTICE file distributed with
|
|
* this work for additional information regarding copyright ownership. The
|
|
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
|
* "License"); you may not use this file except in compliance with the
|
|
* License. You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
* License for the specific language governing permissions and limitations
|
|
* under the License.
|
|
*
|
|
* Alternatively, the contents of this file may be used under the terms of
|
|
* the BSD-3-Clause license:
|
|
*
|
|
* SPDX-License-Identifier: BSD-3-Clause
|
|
*
|
|
* Copyright (c) 2024 Saurav Pal
|
|
*
|
|
* 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.
|
|
* 3. Neither the name of the author nor the names of its contributors may
|
|
* be used to endorse or promote products derived from this software
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
|
|
*
|
|
****************************************************************************/
|
|
|
|
#ifndef __FS_MNEMOFS_MNEMOFS_H
|
|
#define __FS_MNEMOFS_MNEMOFS_H
|
|
|
|
/****************************************************************************
|
|
* Included Files
|
|
****************************************************************************/
|
|
|
|
#include <debug.h>
|
|
#include <nuttx/fs/fs.h>
|
|
#include <nuttx/list.h>
|
|
#include <nuttx/mtd/mtd.h>
|
|
|
|
/****************************************************************************
|
|
* Pre-processor Definitions
|
|
****************************************************************************/
|
|
|
|
#define MFS_JRNL_MAGIC "-mfs!j!-"
|
|
#define MFS_MN_MAGIC "-mfs!m!-"
|
|
|
|
#define MFS_CEILDIVIDE(num, denom) (((num) + ((denom) - 1)) / (denom))
|
|
#define MFS_UPPER8(num) (((num) + 7) & (-8))
|
|
|
|
#define MFS_BLK2PG(sb, blk) ((blk) << (sb)->log_pg_in_blk)
|
|
#define MFS_PG2BLK(sb, pg) ((pg) >> (sb)->log_pg_in_blk)
|
|
#define MFS_PG2BLKPGOFF(sb, pg) ((pg) % (1 << (sb)->log_pg_in_blk))
|
|
|
|
#define MFS_LOCK(sb) ((sb)->fs_lock)
|
|
#define MFS_PGSZ(sb) ((sb)->pg_sz)
|
|
#define MFS_LRU(sb) ((sb)->lru)
|
|
#define MFS_BLKSZ(sb) ((sb)->blk_sz)
|
|
#define MFS_MN(sb) ((sb)->mn)
|
|
#define MFS_JRNL(sb) ((sb)->j_state)
|
|
#define MFS_LOGPGSZ(sb) (MFS_CEILDIVIDE((sb)->log_pg_sz, 8))
|
|
#define MFS_PGINBLK(sb) ((sb)->pg_in_blk)
|
|
#define MFS_MTD(sb) ((sb)->drv->u.i_mtd)
|
|
#define MFS_RWBUF(sb) ((sb)->rw_buf)
|
|
#define MFS_BA(sb) ((sb)->ba_state)
|
|
#define MFS_NBLKS(sb) ((sb)->n_blks)
|
|
#define MFS_OFILES(sb) ((sb)->of)
|
|
#define MFS_FLUSH(sb) ((sb)->flush)
|
|
#define MFS_NPGS(sb) (MFS_NBLKS(sb) * MFS_PGINBLK(sb))
|
|
|
|
#define MFS_HASHSZ 16
|
|
#define MFS_CTZ_SZ(l) ((l)->sz)
|
|
#define MFS_DIRENTSZ(dirent) ((2 * 2) + 4 + (16 * 3) + 8 + 1 \
|
|
+ (dirent)->namelen)
|
|
|
|
#define MFS_JRNL_LIM(sb) (MFS_JRNL(sb).n_blks / 2)
|
|
#define MFS_TRAVERSE_INITSZ 8
|
|
|
|
/****************************************************************************
|
|
* Public Types
|
|
****************************************************************************/
|
|
|
|
typedef uint32_t mfs_t;
|
|
|
|
enum
|
|
{
|
|
MFS_PG_USED,
|
|
MFS_PG_FREE,
|
|
MFS_BLK_BAD,
|
|
MFS_BLK_ERASABLE,
|
|
MFS_BLK_FREE,
|
|
MFS_BLK_USED,
|
|
};
|
|
|
|
enum MFS_PATH_FLAGS
|
|
{
|
|
MFS_ISDIR = (1 << 0), /* Path is a directory. */
|
|
MFS_ISFILE = (1 << 1), /* Path is a file. */
|
|
MFS_EXIST = (1 << 2), /* Path Exists */
|
|
MFS_FINPATH = (1 << 3), /* File in midele of path before bottom most
|
|
* child. Not reachable.
|
|
*/
|
|
MFS_P_EXIST = (1 << 4), /* Parent of the bottom most element exists. */
|
|
MFS_P_ISDIR = (1 << 5), /* Parent is a directory. */
|
|
};
|
|
|
|
struct mfs_ctz_s
|
|
{
|
|
mfs_t pg_e;
|
|
mfs_t idx_e;
|
|
};
|
|
|
|
struct mfs_path_s
|
|
{
|
|
struct mfs_ctz_s ctz;
|
|
mfs_t off;
|
|
mfs_t sz;
|
|
};
|
|
|
|
struct mfs_ba_state_s
|
|
{
|
|
mfs_t s_blk; /* Start block */
|
|
mfs_t c_pg; /* Current page */
|
|
FAR mfs_t *k_del; /* Delete counter for blocks. */
|
|
size_t n_bmap_upgs;
|
|
FAR uint8_t *bmap_upgs; /* Bitmap of used pages. */
|
|
};
|
|
|
|
struct mfs_mn_s
|
|
{
|
|
mfs_t pg; /* Only mblk1's pg will be used here. */
|
|
mfs_t jrnl_blk; /* Start of journal. */
|
|
mfs_t mblk_idx; /* Index for next MN entry inside blk. */
|
|
struct mfs_ctz_s root_ctz;
|
|
mfs_t root_sz;
|
|
struct timespec ts;
|
|
mode_t root_mode;
|
|
struct timespec root_st_atim;
|
|
struct timespec root_st_ctim;
|
|
struct timespec root_st_mtim;
|
|
};
|
|
|
|
struct mfs_jrnl_state_s
|
|
{
|
|
mfs_t mblk1;
|
|
mfs_t mblk2;
|
|
mfs_t n_logs;
|
|
mfs_t log_cpg; /* Current (last) page */
|
|
mfs_t log_cblkidx; /* Current (last) block index. */
|
|
mfs_t log_spg; /* First log's page */
|
|
mfs_t log_sblkidx; /* First jrnl blk index. TODO: jrnlarr > 1 blk. */
|
|
mfs_t jrnlarr_pg;
|
|
mfs_t jrnlarr_pgoff;
|
|
uint16_t n_blks; /* TODO: Does not include the master node. */
|
|
};
|
|
|
|
struct mfs_sb_s
|
|
{
|
|
FAR uint8_t *rw_buf;
|
|
FAR struct inode *drv;
|
|
mutex_t fs_lock;
|
|
mfs_t sb_blk; /* Block number of the superblock */
|
|
mfs_t pg_sz;
|
|
uint8_t log_pg_sz;
|
|
mfs_t blk_sz;
|
|
uint8_t log_blk_sz;
|
|
mfs_t n_blks;
|
|
uint8_t log_n_blks;
|
|
uint16_t pg_in_blk;
|
|
uint8_t log_pg_in_blk;
|
|
struct mfs_mn_s mn; /* Master Node */
|
|
struct mfs_jrnl_state_s j_state; /* Journal State */
|
|
struct mfs_ba_state_s ba_state; /* Block Allocator State */
|
|
struct list_node lru;
|
|
struct list_node of; /* open files. */
|
|
bool flush;
|
|
};
|
|
|
|
/* This is for *dir VFS methods. */
|
|
|
|
struct mfs_fsdirent
|
|
{
|
|
struct fs_dirent_s base; /* VFS directory structure */
|
|
uint8_t idx; /* This only goes from 0 for ., 1 for .. and
|
|
* 2 for others.
|
|
*/
|
|
FAR struct mfs_pitr_s *pitr;
|
|
FAR struct mfs_path_s *path;
|
|
mfs_t depth;
|
|
};
|
|
|
|
/* LRU Delta */
|
|
|
|
struct mfs_delta_s
|
|
{
|
|
struct list_node list;
|
|
mfs_t off;
|
|
mfs_t n_b;
|
|
FAR char *upd;
|
|
};
|
|
|
|
/* LRU Node */
|
|
|
|
struct mfs_node_s
|
|
{
|
|
struct list_node list;
|
|
struct list_node delta;
|
|
mfs_t n_list;
|
|
mfs_t depth;
|
|
mfs_t sz;
|
|
mfs_t range_min;
|
|
mfs_t range_max;
|
|
struct timespec st_mtim;
|
|
struct timespec st_atim;
|
|
struct timespec st_ctim;
|
|
FAR struct mfs_path_s *path;
|
|
};
|
|
|
|
/* Common Part Open File Descriptor */
|
|
|
|
struct mfs_ocom_s
|
|
{
|
|
bool new_ent;
|
|
mfs_t sz; /* Current file size. */
|
|
mfs_t off;
|
|
mfs_t depth;
|
|
uint8_t refcount;
|
|
int oflags;
|
|
FAR struct mfs_path_s *path;
|
|
};
|
|
|
|
/* Open part for file descriptors. */
|
|
|
|
struct mfs_ofd_s
|
|
{
|
|
struct list_node list;
|
|
FAR struct mfs_ocom_s *com;
|
|
};
|
|
|
|
struct mfs_dirent_s
|
|
{
|
|
uint16_t name_hash; /* Should be at start to improve efficiency. */
|
|
uint16_t mode;
|
|
mfs_t sz;
|
|
struct timespec st_atim; /* Time of last access */
|
|
struct timespec st_mtim; /* Time of last modification */
|
|
struct timespec st_ctim; /* Time of last status change */
|
|
struct mfs_ctz_s ctz;
|
|
uint8_t namelen;
|
|
FAR char name[];
|
|
};
|
|
|
|
/* Parent iterator */
|
|
|
|
struct mfs_pitr_s
|
|
{
|
|
struct mfs_path_s p; /* Parent representation */
|
|
mfs_t depth;
|
|
mfs_t c_off; /* Current offset. */
|
|
};
|
|
|
|
/* TODO: depth >= 1 */
|
|
|
|
/* IMP TODO: sizeof(x) != size of buffer required to store it. Need to fix. */
|
|
|
|
/****************************************************************************
|
|
* Public Data
|
|
****************************************************************************/
|
|
|
|
#ifdef __cplusplus
|
|
#define EXTERN extern "C"
|
|
extern "C"
|
|
{
|
|
#else
|
|
#define EXTERN extern
|
|
#endif
|
|
|
|
/****************************************************************************
|
|
* Inline Functions
|
|
****************************************************************************/
|
|
|
|
/****************************************************************************
|
|
* Name: mfs_blkremsz
|
|
*
|
|
* Description:
|
|
* Given a page and a page offset, it returns the bytes left in the entire
|
|
* block after the offset location.
|
|
*
|
|
* Input Parameters:
|
|
* sb - Superblock instance of the device.
|
|
* pg - Page number.
|
|
* pgoff - Page offset.
|
|
*
|
|
* Returned Value:
|
|
* Bytes left in the block.
|
|
*
|
|
****************************************************************************/
|
|
|
|
static mfs_t inline mfs_blkremsz(FAR const struct mfs_sb_s * const sb,
|
|
mfs_t pg, mfs_t pgoff)
|
|
{
|
|
return MFS_BLKSZ(sb) - (MFS_PG2BLKPGOFF(sb, pg) * sb->pg_sz + pgoff);
|
|
}
|
|
|
|
static inline mfs_t mfs_ctz(const uint32_t x)
|
|
{
|
|
if (predict_false(x == 0))
|
|
{
|
|
/* Special case, since we're using this for the CTZ skip list. The 0th
|
|
* block has no pointers.
|
|
*/
|
|
|
|
return 0;
|
|
}
|
|
|
|
#if defined(__GNUC__)
|
|
return __builtin_ctz(x);
|
|
#else
|
|
uint32_t c;
|
|
|
|
/* Credits:
|
|
* http://graphics.stanford.edu/~seander/bithacks.html#ZerosOnRightBinSearch
|
|
*/
|
|
|
|
if (x & 0x1)
|
|
{
|
|
/* special case for odd x (assumed to happen half of the time) */
|
|
|
|
c = 0;
|
|
}
|
|
else
|
|
{
|
|
c = 1;
|
|
if ((x & 0xffff) == 0)
|
|
{
|
|
x >>= 16;
|
|
c += 16;
|
|
}
|
|
if ((x & 0xff) == 0)
|
|
{
|
|
x >>= 8;
|
|
c += 8;
|
|
}
|
|
if ((x & 0xf) == 0)
|
|
{
|
|
x >>= 4;
|
|
c += 4;
|
|
}
|
|
if ((x & 0x3) == 0)
|
|
{
|
|
x >>= 2;
|
|
c += 2;
|
|
}
|
|
c -= x & 0x1;
|
|
}
|
|
return c;
|
|
#endif
|
|
}
|
|
|
|
static inline mfs_t mfs_clz(const uint32_t x)
|
|
{
|
|
if (predict_false(x == UINT32_MAX))
|
|
{
|
|
/* Special case, since we're using this for the CTZ skip list. The 0th
|
|
* block has no pointers.
|
|
*/
|
|
|
|
return 0;
|
|
}
|
|
|
|
#if defined(__GNUC__)
|
|
return __builtin_clz(x);
|
|
#else
|
|
return 0; /* TODO */
|
|
#endif
|
|
}
|
|
|
|
static inline mfs_t mfs_popcnt(mfs_t x)
|
|
{
|
|
#if defined(__GNUC__)
|
|
return __builtin_popcount(x);
|
|
#else
|
|
/* Can be found at:
|
|
* http://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetKernighan
|
|
*/
|
|
|
|
mfs_t c;
|
|
for (c = 0; x; c++)
|
|
{
|
|
x &= x - 1;
|
|
}
|
|
|
|
#endif
|
|
}
|
|
|
|
/****************************************************************************
|
|
* Public Function Prototypes
|
|
****************************************************************************/
|
|
|
|
/* mnemofs.c */
|
|
|
|
int mnemofs_flush(FAR struct mfs_sb_s *sb);
|
|
|
|
/* mnemofs_journal.c */
|
|
|
|
/****************************************************************************
|
|
* Name: mfs_jrnl_init
|
|
*
|
|
* Description:
|
|
* Initialize journal if device is already formatted.
|
|
*
|
|
* Input Parameters:
|
|
* sb - Superblock instance of the device.
|
|
* blk - First block of the journal.
|
|
*
|
|
* Returned Value:
|
|
* 0 - OK
|
|
* < 0 - Error
|
|
*
|
|
****************************************************************************/
|
|
|
|
int mfs_jrnl_init(FAR struct mfs_sb_s * const sb, mfs_t blk);
|
|
|
|
/****************************************************************************
|
|
* Name: mfs_jrnl_fmt
|
|
*
|
|
* Description:
|
|
* Format a journal to the device.
|
|
*
|
|
* Input Parameters:
|
|
* sb - Superblock instance of the device.
|
|
* blk1 - First master block for the journal.
|
|
* blk2 - Second master block for the journal.
|
|
*
|
|
* Returned Value:
|
|
* 0 - OK
|
|
* < 0 - Error
|
|
*
|
|
* Assumptions/Limitations:
|
|
* If blk1 == 0 and blk2 == 0, this means that this will also format in the
|
|
* master blocks. If this is not satisfied, the provided values will be
|
|
* taken to denote the master nodes.
|
|
*
|
|
****************************************************************************/
|
|
|
|
int mfs_jrnl_fmt(FAR struct mfs_sb_s * const sb, mfs_t *blk1, mfs_t *blk2,
|
|
FAR mfs_t *jrnl_blk);
|
|
|
|
/****************************************************************************
|
|
* Name: mfs_jrnl_free
|
|
*
|
|
* Description:
|
|
* Free the journal.
|
|
*
|
|
* Input Parameters:
|
|
* sb - Superblock instance of the device.
|
|
*
|
|
****************************************************************************/
|
|
|
|
void mfs_jrnl_free(FAR struct mfs_sb_s * const sb);
|
|
|
|
/****************************************************************************
|
|
* Name: mfs_jrnl_blkidx2blk
|
|
*
|
|
* Description:
|
|
* Gets the block number of a journal block at an index.
|
|
*
|
|
* Input Parameters:
|
|
* sb - Superblock instance of the device.
|
|
* blk_idx - Index of the block who's block number to find.
|
|
*
|
|
* Returned Value:
|
|
* Block number.
|
|
*
|
|
* Assumptions/Limitations:
|
|
* Assumes valid index. This index can also include master blocks. Also
|
|
* assumes, for now, that the entire journal array can fit in the first
|
|
* block.
|
|
*
|
|
****************************************************************************/
|
|
|
|
mfs_t mfs_jrnl_blkidx2blk(FAR const struct mfs_sb_s * const sb,
|
|
const mfs_t blk_idx);
|
|
|
|
/****************************************************************************
|
|
* Name: mfs_jrnl_updatedinfo
|
|
*
|
|
* Description:
|
|
* Update the path information from the journal.
|
|
*
|
|
* Input Parameters:
|
|
* sb - Superblock instance of the device.
|
|
* path - "Base state" path.
|
|
* depth - Path depth.
|
|
*
|
|
* Returned Value:
|
|
* 0 - OK
|
|
* < 0 - Error
|
|
*
|
|
* Assumptions/Limitations:
|
|
* This applies updates over data that is already gathered from the data
|
|
* section of the flash. The data section is the "base state" over which
|
|
* the updates in the journal are applied.
|
|
*
|
|
****************************************************************************/
|
|
|
|
int mfs_jrnl_updatedinfo(FAR const struct mfs_sb_s * const sb,
|
|
FAR struct mfs_path_s * const path,
|
|
const mfs_t depth);
|
|
|
|
/****************************************************************************
|
|
* Name: mfs_jrnl_wrlog
|
|
*
|
|
* Description:
|
|
* Write a log for LRU node when its popped from the LRU.
|
|
*
|
|
* Input Parameters:
|
|
* sb - Superblock instance of the device.
|
|
* node - LRU node.
|
|
* loc_new - New location of the CTZ skip list.
|
|
* sz_new - New size of the CTZ skip list.
|
|
*
|
|
* Returned Value:
|
|
* 0 - OK
|
|
* < 0 - Error
|
|
*
|
|
* Assumptions/Limitations:
|
|
* When a node from LRU is flushed, it's written to the data in any space
|
|
* that is available according to the block allocator, and the new location
|
|
* is recorded as a log along with the old location. Any log of this same
|
|
* CTZ skip list in the journal will use this "snapshot" of the location,
|
|
* ie. the updated path will be used until another log of the same CTZ
|
|
* skip list is stored, after which the path will be updated again, and
|
|
* so on.
|
|
*
|
|
****************************************************************************/
|
|
|
|
int mfs_jrnl_wrlog(FAR struct mfs_sb_s * const sb,
|
|
FAR const struct mfs_node_s *node,
|
|
const struct mfs_ctz_s loc_new, const mfs_t sz_new);
|
|
|
|
/****************************************************************************
|
|
* Name: mfs_jrnl_flush
|
|
*
|
|
* Description:
|
|
* Flush the entire journal. This is the entry point of the entire flush
|
|
* operation and includes messing with the master node as well.
|
|
*
|
|
* Input Parameters:
|
|
* sb - Superblock instance of the device.
|
|
*
|
|
* Returned Value:
|
|
* 0 - OK
|
|
* < 0 - Error
|
|
*
|
|
****************************************************************************/
|
|
|
|
int mfs_jrnl_flush(FAR struct mfs_sb_s * const sb);
|
|
|
|
/****************************************************************************
|
|
* Name: mfs_jrnl_isempty
|
|
*
|
|
* Description:
|
|
* Check if the journal is empty.
|
|
*
|
|
* Input Parameters:
|
|
* sb - Superblock instance of the device.
|
|
*
|
|
* Returned Value:
|
|
* True is the journal is empty, false otherwise.
|
|
*
|
|
****************************************************************************/
|
|
|
|
bool mfs_jrnl_isempty(FAR const struct mfs_sb_s * const sb);
|
|
|
|
/* mnemofs_blkalloc.c */
|
|
|
|
/****************************************************************************
|
|
* Name: mfs_ba_init
|
|
*
|
|
* Description:
|
|
* Formats and initializes the block allocator.
|
|
*
|
|
* Input Parameters:
|
|
* sb - Superblock instance of the device.
|
|
*
|
|
* Returned Value:
|
|
* 0 - OK
|
|
* -ENOMEM - No memory left.
|
|
*
|
|
****************************************************************************/
|
|
|
|
int mfs_ba_fmt(FAR struct mfs_sb_s * const sb);
|
|
|
|
/****************************************************************************
|
|
* Name: mfs_ba_init
|
|
*
|
|
* Description:
|
|
* Initializes the block allocator.
|
|
*
|
|
* Input Parameters:
|
|
* sb - Superblock instance of the device.
|
|
*
|
|
* Returned Value:
|
|
* 0 - OK
|
|
* -ENOMEM - No memory left.
|
|
*
|
|
****************************************************************************/
|
|
|
|
int mfs_ba_init(FAR struct mfs_sb_s * const sb);
|
|
|
|
/****************************************************************************
|
|
* Name: mfs_ba_getpg
|
|
*
|
|
* Description:
|
|
* Returns an allocated page.
|
|
*
|
|
* Input Parameters:
|
|
* sb - Superblock instance of the device.
|
|
*
|
|
* Returned Value:
|
|
* 0 - No more space left
|
|
* > 0 - Page number
|
|
*
|
|
* Assumptions/Limitations:
|
|
* This assumes a locked environment when called.
|
|
*
|
|
****************************************************************************/
|
|
|
|
mfs_t mfs_ba_getpg(FAR struct mfs_sb_s * const sb);
|
|
|
|
/****************************************************************************
|
|
* Name: mfs_ba_getblk
|
|
*
|
|
* Description:
|
|
* Returns an allocated block.
|
|
*
|
|
* Input Parameters:
|
|
* sb - Superblock instance of the device.
|
|
*
|
|
* Returned Value:
|
|
* 0 - No more space left
|
|
* > 0 - Block number
|
|
*
|
|
* Assumptions/Limitations:
|
|
* This assumes a locked environment when called.
|
|
*
|
|
****************************************************************************/
|
|
|
|
mfs_t mfs_ba_getblk(FAR struct mfs_sb_s * const sb);
|
|
|
|
/****************************************************************************
|
|
* Name: mfs_ba_pgmarkdel
|
|
*
|
|
* Description:
|
|
* Mark a page as being ready for deletion.
|
|
*
|
|
* Input Parameters:
|
|
* sb - Superblock instance of the device.
|
|
* pg - Page number.
|
|
*
|
|
* Assumptions/Limitations:
|
|
* This assumes a locked environment when called.
|
|
*
|
|
****************************************************************************/
|
|
|
|
void mfs_ba_pgmarkdel(FAR struct mfs_sb_s * const sb, mfs_t pg);
|
|
|
|
/****************************************************************************
|
|
* Name: mfs_ba_blkmarkdel
|
|
*
|
|
* Description:
|
|
* Mark a block as being ready for deletion.
|
|
*
|
|
* Input Parameters:
|
|
* sb - Superblock instance of the device.
|
|
* blk - Block number.
|
|
*
|
|
* Assumptions/Limitations:
|
|
* This assumes a locked environment when called.
|
|
*
|
|
****************************************************************************/
|
|
|
|
void mfs_ba_blkmarkdel(FAR struct mfs_sb_s * const sb, mfs_t blk);
|
|
|
|
/****************************************************************************
|
|
* Name: mfs_ba_delmarked
|
|
*
|
|
* Description:
|
|
* Delete all marked for deletion blocks.
|
|
*
|
|
* Input Parameters:
|
|
* sb - Superblock instance of the device.
|
|
*
|
|
* Returned Value:
|
|
* 0 - OK
|
|
* < 0 - Error
|
|
*
|
|
* Assumptions/Limitations:
|
|
* This assumes a locked environment when called.
|
|
*
|
|
****************************************************************************/
|
|
|
|
int mfs_ba_delmarked(FAR struct mfs_sb_s * const sb);
|
|
|
|
/****************************************************************************
|
|
* Name: mfs_ba_markusedpg
|
|
*
|
|
* Description:
|
|
* Marked page as being used.
|
|
*
|
|
* Input Parameters:
|
|
* sb - Superblock instance of the device.
|
|
* pg - Page number
|
|
*
|
|
* Assumptions/Limitations:
|
|
* This assumes a locked environment when called.
|
|
*
|
|
****************************************************************************/
|
|
|
|
void mfs_ba_markusedpg(FAR struct mfs_sb_s * const sb, mfs_t pg);
|
|
|
|
/****************************************************************************
|
|
* Name: mfs_ba_markusedblk
|
|
*
|
|
* Description:
|
|
* Marked block as being used.
|
|
*
|
|
* Input Parameters:
|
|
* sb - Superblock instance of the device.
|
|
* blk - Block number
|
|
*
|
|
* Assumptions/Limitations:
|
|
* This assumes a locked environment when called.
|
|
*
|
|
****************************************************************************/
|
|
|
|
void mfs_ba_markusedblk(FAR struct mfs_sb_s * const sb, mfs_t blk);
|
|
|
|
/****************************************************************************
|
|
* Name: mfs_ba_getavailpgs
|
|
*
|
|
* Description:
|
|
* Get number of available pages.
|
|
*
|
|
* Input Parameters:
|
|
* sb - Superblock instance of the device.
|
|
* pg - Page number
|
|
*
|
|
* Assumptions/Limitations:
|
|
* This assumes a locked environment when called.
|
|
*
|
|
****************************************************************************/
|
|
|
|
mfs_t mfs_ba_getavailpgs(FAR const struct mfs_sb_s * const sb);
|
|
|
|
/****************************************************************************
|
|
* Name: mfs_ba_free
|
|
*
|
|
* Description:
|
|
* Free the block allocator
|
|
*
|
|
* Input Parameters:
|
|
* sb - Superblock instance of the device.
|
|
*
|
|
* Assumptions/Limitations:
|
|
* This assumes a locked environment when called.
|
|
*
|
|
****************************************************************************/
|
|
|
|
void mfs_ba_free(FAR struct mfs_sb_s * const sb);
|
|
|
|
/* mnemofs_rw.c */
|
|
|
|
/****************************************************************************
|
|
* Name: mfs_isbadblk
|
|
*
|
|
* Description:
|
|
* Is a block bad.
|
|
*
|
|
* Input Parameters:
|
|
* sb - Superblock instance of the device.
|
|
* blk - Block Number
|
|
*
|
|
* Assumptions/Limitations:
|
|
* This assumes a locked environment when called.
|
|
*
|
|
****************************************************************************/
|
|
|
|
int mfs_isbadblk(FAR const struct mfs_sb_s * const sb, mfs_t blk);
|
|
|
|
/****************************************************************************
|
|
* Name: mfs_markbadblk
|
|
*
|
|
* Description:
|
|
* Mark a block as bad.
|
|
*
|
|
* Input Parameters:
|
|
* sb - Superblock instance of the device.
|
|
* blk - Block Number
|
|
*
|
|
* Assumptions/Limitations:
|
|
* This assumes a locked environment when called.
|
|
*
|
|
****************************************************************************/
|
|
|
|
int mfs_markbadblk(FAR const struct mfs_sb_s * const sb, mfs_t blk);
|
|
|
|
/****************************************************************************
|
|
* Name: mfs_write_page
|
|
*
|
|
* Description:
|
|
* Write a page.
|
|
*
|
|
* Input Parameters:
|
|
* sb - Superblock instance of the device.
|
|
* data - Buffer
|
|
* datalen - Length of buffer.
|
|
* pg - Page number.
|
|
* pgoff - Offset into the page.
|
|
*
|
|
* Assumptions/Limitations:
|
|
* This assumes a locked environment when called.
|
|
*
|
|
****************************************************************************/
|
|
|
|
ssize_t mfs_write_page(FAR const struct mfs_sb_s * const sb,
|
|
FAR const char *data, const mfs_t datalen,
|
|
const off_t page, const mfs_t pgoff);
|
|
|
|
/****************************************************************************
|
|
* Name: mfs_read_page
|
|
*
|
|
* Description:
|
|
* Read a page.
|
|
*
|
|
* Input Parameters:
|
|
* sb - Superblock instance of the device.
|
|
* data - Buffer
|
|
* datalen - Length of buffer.
|
|
* pg - Page number.
|
|
* pgoff - Offset into the page.
|
|
*
|
|
* Assumptions/Limitations:
|
|
* This assumes a locked environment when called.
|
|
*
|
|
****************************************************************************/
|
|
|
|
ssize_t mfs_read_page(FAR const struct mfs_sb_s * const sb,
|
|
FAR char *data, const mfs_t datalen, const off_t page,
|
|
const mfs_t pgoff);
|
|
|
|
/****************************************************************************
|
|
* Name: mfs_erase_blk
|
|
*
|
|
* Description:
|
|
* Erase a block.
|
|
*
|
|
* Input Parameters:
|
|
* sb - Superblock instance of the device.
|
|
* blk - Block Number
|
|
*
|
|
* Assumptions/Limitations:
|
|
* This assumes a locked environment when called.
|
|
*
|
|
****************************************************************************/
|
|
|
|
int mfs_erase_blk(FAR const struct mfs_sb_s * const sb, const off_t blk);
|
|
|
|
/****************************************************************************
|
|
* Name: mfs_erase_nblks
|
|
*
|
|
* Description:
|
|
* Erase consecutive blocks.
|
|
*
|
|
* Input Parameters:
|
|
* sb - Superblock instance of the device.
|
|
* blk - Block Number
|
|
*
|
|
* Assumptions/Limitations:
|
|
* This assumes a locked environment when called.
|
|
*
|
|
****************************************************************************/
|
|
|
|
int mfs_erase_nblks(FAR const struct mfs_sb_s * const sb, const off_t blk,
|
|
const size_t n);
|
|
|
|
/* mnemofs_util.c */
|
|
|
|
/****************************************************************************
|
|
* Name: mfs_arrhash
|
|
*
|
|
* Description:
|
|
* Returns an 8-bit hash of an entire array of data.
|
|
*
|
|
* Input Parameters:
|
|
* arr - Data array.
|
|
* len - Length of the array.
|
|
*
|
|
* Returned Value:
|
|
* 16-bit hash of the array.
|
|
*
|
|
****************************************************************************/
|
|
|
|
uint8_t mfs_arrhash(FAR const char *arr, ssize_t len);
|
|
|
|
/* TODO: Put below in place of above. */
|
|
|
|
uint16_t mfs_hash(FAR const char *arr, ssize_t len);
|
|
|
|
/****************************************************************************
|
|
* Name: mfs_ser_8
|
|
*
|
|
* Description:
|
|
* Serialize a 8 bit type into output.
|
|
*
|
|
* Input Parameters:
|
|
* n - 8 bit to serialize
|
|
* out - Output array where to serialize.
|
|
*
|
|
* Returned Value:
|
|
* Pointer to byte after the end of serialized value.
|
|
*
|
|
****************************************************************************/
|
|
|
|
FAR char *mfs_ser_8(const uint8_t n, FAR char * const out);
|
|
|
|
/****************************************************************************
|
|
* Name: mfs_deser_8
|
|
*
|
|
* Description:
|
|
* Deserialize a 8 bit type from input.
|
|
*
|
|
* Input Parameters:
|
|
* in - Input array from where to deserialize.
|
|
* n - 8 bit to deserialize
|
|
*
|
|
* Returned Value:
|
|
* Pointer to byte after the end of serialized value.
|
|
*
|
|
****************************************************************************/
|
|
|
|
FAR const char *mfs_deser_8(FAR const char * const in, uint8_t *n);
|
|
|
|
/****************************************************************************
|
|
* Name: mfs_ser_str
|
|
*
|
|
* Description:
|
|
* Serialize a string into output.
|
|
*
|
|
* Input Parameters:
|
|
* str - String to serialize
|
|
* len - Length of string
|
|
* out - Output array where to serialize.
|
|
*
|
|
* Returned Value:
|
|
* Pointer to byte after the end of serialized value.
|
|
*
|
|
****************************************************************************/
|
|
|
|
FAR char *mfs_ser_str(FAR const char * const str, const mfs_t len,
|
|
FAR char * const out);
|
|
|
|
/****************************************************************************
|
|
* Name: mfs_deser_str
|
|
*
|
|
* Description:
|
|
* Deserialize a string from intput.
|
|
*
|
|
* Input Parameters:
|
|
* in - Intput array from where to deserialize.
|
|
* str - String to deserialize
|
|
* len - Length of string
|
|
*
|
|
* Returned Value:
|
|
* Pointer to byte after the end of serialized value.
|
|
*
|
|
****************************************************************************/
|
|
|
|
FAR const char *mfs_deser_str(FAR const char * const in,
|
|
FAR char * const str, const mfs_t len);
|
|
|
|
/****************************************************************************
|
|
* Name: mfs_ser_mfs
|
|
*
|
|
* Description:
|
|
* Serialize a mfs_t type into output.
|
|
*
|
|
* Input Parameters:
|
|
* n - mfs_t to serialize
|
|
* out - Output array where to serialize.
|
|
*
|
|
* Returned Value:
|
|
* Pointer to byte after the end of serialized value.
|
|
*
|
|
****************************************************************************/
|
|
|
|
FAR char *mfs_ser_mfs(const mfs_t n, FAR char * const out);
|
|
|
|
/****************************************************************************
|
|
* Name: mfs_deser_mfs
|
|
*
|
|
* Description:
|
|
* Deserialize a mfs_t type from input..
|
|
*
|
|
* Input Parameters:
|
|
* in - Input array from where to deserialize.
|
|
* n - mfs_t to deserialize
|
|
*
|
|
* Returned Value:
|
|
* Pointer to byte after the end of serialized value.
|
|
*
|
|
****************************************************************************/
|
|
|
|
FAR const char *mfs_deser_mfs(FAR const char * const in,
|
|
FAR mfs_t * const n);
|
|
|
|
/****************************************************************************
|
|
* Name: mfs_ser_ctz
|
|
*
|
|
* Description:
|
|
* Serialize a mfs_ctz_store_s type into output.
|
|
*
|
|
* Input Parameters:
|
|
* x - mfs_ctz_s to serialize
|
|
* out - Output array where to serialize.
|
|
*
|
|
* Returned Value:
|
|
* Pointer to byte after the end of serialized value.
|
|
*
|
|
****************************************************************************/
|
|
|
|
FAR char *mfs_ser_ctz(FAR const struct mfs_ctz_s * const x,
|
|
FAR char * const out);
|
|
|
|
/****************************************************************************
|
|
* Name: mfs_deser_ctz
|
|
*
|
|
* Description:
|
|
* Deserialize a mfs_ctz_store_s type into output.
|
|
*
|
|
* Input Parameters:
|
|
* in - Input array from where to deserialize.
|
|
* x - mfs_ctz_s to deserialize
|
|
*
|
|
* Returned Value:
|
|
* Pointer to byte after the end of serialized value.
|
|
*
|
|
****************************************************************************/
|
|
|
|
FAR const char *mfs_deser_ctz(FAR const char * const in,
|
|
FAR struct mfs_ctz_s * const x);
|
|
|
|
FAR char *mfs_ser_path(FAR const struct mfs_path_s * const x,
|
|
FAR char * const out);
|
|
|
|
FAR const char *mfs_deser_path(FAR const char * const in,
|
|
FAR struct mfs_path_s * const x);
|
|
|
|
/****************************************************************************
|
|
* Name: mfs_ser_timespec
|
|
*
|
|
* Description:
|
|
* Serialize timespec.
|
|
*
|
|
* Input Parameters:
|
|
* x - Value to serialize
|
|
* out - Output array where to serialize.
|
|
*
|
|
* Returned Value:
|
|
* Pointer to byte after the end of serialized value.
|
|
*
|
|
****************************************************************************/
|
|
|
|
FAR char *mfs_ser_timespec(FAR const struct timespec * const x,
|
|
FAR char * const out);
|
|
|
|
/****************************************************************************
|
|
* Name: mfs_deser_timespec
|
|
*
|
|
* Description:
|
|
* Deserialize timespec.
|
|
*
|
|
* Input Parameters:
|
|
* in - Input array from where to deserialize.
|
|
* x - Value to deserialize
|
|
*
|
|
* Returned Value:
|
|
* Pointer to byte after the end of serialized value.
|
|
*
|
|
****************************************************************************/
|
|
|
|
FAR const char *mfs_deser_timespec(FAR const char * const in,
|
|
FAR struct timespec * const x);
|
|
|
|
/****************************************************************************
|
|
* Name: mfs_ser_16
|
|
*
|
|
* Description:
|
|
* Serialize 16 bit values.
|
|
*
|
|
* Input Parameters:
|
|
* x - Value to serialize
|
|
* out - Output array where to serialize.
|
|
*
|
|
* Returned Value:
|
|
* Pointer to byte after the end of serialized value.
|
|
*
|
|
****************************************************************************/
|
|
|
|
FAR char *mfs_ser_16(const uint16_t n, FAR char * const out);
|
|
|
|
/****************************************************************************
|
|
* Name: mfs_deser_16
|
|
*
|
|
* Description:
|
|
* Deserialize 16 bit value.
|
|
*
|
|
* Input Parameters:
|
|
* in - Input array from where to deserialize.
|
|
* x - Value to deserialize
|
|
*
|
|
* Returned Value:
|
|
* Pointer to byte after the end of serialized value.
|
|
*
|
|
****************************************************************************/
|
|
|
|
FAR const char *mfs_deser_16(FAR const char * const in, FAR uint16_t *n);
|
|
|
|
/****************************************************************************
|
|
* Name: mfs_v2n
|
|
*
|
|
* Description:
|
|
* v2n(n) math function.
|
|
*
|
|
* Input Parameters:
|
|
* n - Number.
|
|
*
|
|
* Returned Value:
|
|
* v2n(n).
|
|
*
|
|
****************************************************************************/
|
|
|
|
mfs_t mfs_v2n(mfs_t n);
|
|
|
|
/****************************************************************************
|
|
* Name: mfs_set_msb
|
|
*
|
|
* Description:
|
|
* The mosr significant set bit location.
|
|
*
|
|
* Input Parameters:
|
|
* n - Number.
|
|
*
|
|
* Returned Value:
|
|
* Number after setting the bit.
|
|
*
|
|
****************************************************************************/
|
|
|
|
mfs_t mfs_set_msb(mfs_t n);
|
|
|
|
bool mfs_ctz_eq(FAR const struct mfs_ctz_s * const a,
|
|
FAR const struct mfs_ctz_s * const b);
|
|
|
|
bool mfs_path_eq(FAR const struct mfs_path_s * const a,
|
|
FAR const struct mfs_path_s * const b);
|
|
|
|
/* mnemofs_ctz.c */
|
|
|
|
/****************************************************************************
|
|
* Name: mfs_ctz_rdfromoff_new
|
|
*
|
|
* Description:
|
|
* Read from a specific offset into the data in a CTZ file. New version.
|
|
*
|
|
* Input Parameters:
|
|
* sb - Superblock instance of the device.
|
|
* ctz - CTZ list.
|
|
* data_off - Offset into the data.
|
|
* len - Length of the buffer.
|
|
* buf - Buffer to store read contents.
|
|
*
|
|
* Assumptions/Limitations:
|
|
* The CTZ list provided should be the updated location from the journal.
|
|
*
|
|
****************************************************************************/
|
|
|
|
int mfs_ctz_rdfromoff(FAR const struct mfs_sb_s * const sb,
|
|
const struct mfs_ctz_s ctz, mfs_t data_off,
|
|
mfs_t len, FAR char * buf);
|
|
|
|
/****************************************************************************
|
|
* Name: mfs_ctz_wrtnode
|
|
*
|
|
* Description:
|
|
* Write an LRU node to the flash. It also adds a log of it to the journal.
|
|
*
|
|
* Input Parameters:
|
|
* sb - Superblock instance of the device.
|
|
* node - LRU node
|
|
*
|
|
* Assumptions/Limitations:
|
|
* - Assumes path is updated by journal. This will also write corresponding
|
|
* journal log.
|
|
*
|
|
* - This is the most computationally heavy part of the entire file system
|
|
* from a human POV, and one of the most for MCU or computer (as init
|
|
* methods are heavier).
|
|
*
|
|
****************************************************************************/
|
|
|
|
int mfs_ctz_wrtnode(FAR struct mfs_sb_s * const sb,
|
|
FAR const struct mfs_node_s * const node,
|
|
FAR struct mfs_ctz_s *new_loc);
|
|
|
|
/****************************************************************************
|
|
* Name: mfs_ctz_travel
|
|
*
|
|
* Description:
|
|
* From CTZ block at page `pg_src` and index `idx_src`, give the page
|
|
* number of index `idx_dest`.
|
|
*
|
|
* The source is preferably the last CTZ block in the CTZ list, but it can
|
|
* realistically be any CTZ block in the CTZ list whos position is known.
|
|
* However, `idx_dest <= idx_src` has to be followed. Takes O(log(n))
|
|
* complexity to travel.
|
|
*
|
|
* Input Parameters:
|
|
* sb - Superblock instance of the device.
|
|
* idx_src - Index of the source ctz block.
|
|
* pg_src - Page number of the source ctz block.
|
|
* idx_dest - Index of the destination ctz block.
|
|
*
|
|
* Returned Value:
|
|
* The page number corresponding to `idx_dest`.
|
|
*
|
|
* Assumptions/Limitations:
|
|
* `idx_dest <= idx_src`.
|
|
*
|
|
****************************************************************************/
|
|
|
|
mfs_t mfs_ctz_travel(FAR const struct mfs_sb_s * const sb,
|
|
mfs_t idx_src, mfs_t pg_src, mfs_t idx_dest);
|
|
|
|
/* mnemofs_lru.c */
|
|
|
|
/****************************************************************************
|
|
* Name: mfs_lru_ctzflush
|
|
*
|
|
* Description:
|
|
* Flush the updates of a CTZ list inside the LRU to the flash.
|
|
*
|
|
* Input Parameters:
|
|
* sb - Superblock instance of the device.
|
|
* path - CTZ representation of the relpath.
|
|
* depth - Depth of path.
|
|
*
|
|
****************************************************************************/
|
|
|
|
int mfs_lru_ctzflush(FAR struct mfs_sb_s * const sb,
|
|
FAR struct mfs_path_s * const path, const mfs_t depth);
|
|
|
|
/****************************************************************************
|
|
* Name: mfs_lru_del
|
|
*
|
|
* Description:
|
|
* Delete instruction to LRU.
|
|
*
|
|
* Input Parameters:
|
|
* sb - Superblock instance of the device.
|
|
* off - Offset into the data.
|
|
* bytes - Number of bytes to delete.
|
|
* path - CTZ representation of the relpath.
|
|
* depth - Depth of path.
|
|
*
|
|
****************************************************************************/
|
|
|
|
int mfs_lru_del(FAR struct mfs_sb_s * const sb, const mfs_t data_off,
|
|
mfs_t bytes, FAR struct mfs_path_s * const path,
|
|
const mfs_t depth);
|
|
|
|
/****************************************************************************
|
|
* Name: mfs_lru_wr
|
|
*
|
|
* Description:
|
|
* Write to LRU
|
|
*
|
|
* Input Parameters:
|
|
* sb - Superblock instance of the device.
|
|
* data_off - Offset into the data.
|
|
* bytes - Number of bytes to delete.
|
|
* path - CTZ representation of the relpath.
|
|
* depth - Depth of path.
|
|
* buf - Buffer.
|
|
*
|
|
****************************************************************************/
|
|
|
|
int mfs_lru_wr(FAR struct mfs_sb_s * const sb, const mfs_t data_off,
|
|
mfs_t bytes, FAR struct mfs_path_s * const path,
|
|
const mfs_t depth, FAR const char *buf);
|
|
|
|
/****************************************************************************
|
|
* Name: mfs_lru_init
|
|
*
|
|
* Description:
|
|
* Initialize LRU.
|
|
*
|
|
* Input Parameters:
|
|
* sb - Superblock instance of the device.
|
|
*
|
|
****************************************************************************/
|
|
|
|
void mfs_lru_init(FAR struct mfs_sb_s * const sb);
|
|
|
|
/****************************************************************************
|
|
* Name: mfs_lru_rdfromoff
|
|
*
|
|
* Description:
|
|
* Read updated data from an offset upto a certain number of bytes.
|
|
*
|
|
* Input Parameters:
|
|
* sb - Superblock instance of the device.
|
|
* data_off - Offset into the data.
|
|
* path - CTZ representation of the relpath.
|
|
* depth - Depth of path.
|
|
* buf - Buffer to populate with data.
|
|
* buflen - Length of data to read.
|
|
*
|
|
****************************************************************************/
|
|
|
|
int mfs_lru_rdfromoff(FAR const struct mfs_sb_s * const sb,
|
|
const mfs_t data_off,
|
|
FAR struct mfs_path_s * const path, const mfs_t depth,
|
|
FAR char *buf, const mfs_t buflen);
|
|
|
|
/****************************************************************************
|
|
* Name: mfs_lru_updatedinfo
|
|
*
|
|
* Description:
|
|
* Update information of the path.
|
|
*
|
|
* Input Parameters:
|
|
* sb - Superblock instance of the device.
|
|
* path - CTZ representation of the relpath.
|
|
* depth - Depth of path.
|
|
*
|
|
* Assumptions/Limitations:
|
|
* The will update path.
|
|
*
|
|
****************************************************************************/
|
|
|
|
int mfs_lru_updatedinfo(FAR const struct mfs_sb_s * const sb,
|
|
FAR struct mfs_path_s * const path,
|
|
const mfs_t depth);
|
|
|
|
/****************************************************************************
|
|
* Name: mfs_lru_updatectz
|
|
*
|
|
* Description:
|
|
* Update CTZ location of an fs object.
|
|
*
|
|
* Input Parameters:
|
|
* sb - Superblock instance of the device.
|
|
* path - Old CTZ representation of the relpath.
|
|
* depth - Depth of path.
|
|
* new_ctz - New CTZ location.
|
|
*
|
|
* Assumptions/Limitations:
|
|
* The update the CTZ portion of the direntry in the parent.
|
|
* This updates the path as well.
|
|
*
|
|
****************************************************************************/
|
|
|
|
int mfs_lru_updatectz(FAR struct mfs_sb_s * sb,
|
|
FAR struct mfs_path_s * const path, const mfs_t depth,
|
|
const struct mfs_ctz_s new_ctz, mfs_t new_sz);
|
|
|
|
bool mfs_lru_isempty(FAR struct mfs_sb_s * const sb);
|
|
int mfs_lru_flush(FAR struct mfs_sb_s * const sb);
|
|
|
|
/* mnemofs_master.c */
|
|
|
|
/****************************************************************************
|
|
* Name: mfs_mn_init
|
|
*
|
|
* Description:
|
|
* Initialize master node by reading from the flash.
|
|
*
|
|
* Input Parameters:
|
|
* sb - Superblock instance of the device.
|
|
* jrnl_blk - First block of the journal.
|
|
*
|
|
* Returned Value:
|
|
* 0 - OK
|
|
* < 0 - Error
|
|
*
|
|
* Assumptions/Limitations:
|
|
* The journal will have to be initialized before this.
|
|
*
|
|
****************************************************************************/
|
|
|
|
int mfs_mn_init(FAR struct mfs_sb_s * const sb, const mfs_t jrnl_blk);
|
|
|
|
/****************************************************************************
|
|
* Name: mfs_mn_fmt
|
|
*
|
|
* Description:
|
|
* Format a master node.
|
|
*
|
|
* Input Parameters:
|
|
* sb - Superblock instance of the device.
|
|
* jrnl_blk - First block of the journal.
|
|
*
|
|
* Returned Value:
|
|
* 0 - OK
|
|
* < 0 - Error
|
|
*
|
|
* Assumptions/Limitations:
|
|
* The journal will have to be formatted before this.
|
|
*
|
|
****************************************************************************/
|
|
|
|
int mfs_mn_fmt(FAR struct mfs_sb_s * const sb, const mfs_t blk1,
|
|
const mfs_t blk2, const mfs_t jrnl_blk);
|
|
|
|
/****************************************************************************
|
|
* Name: mfs_mn_move
|
|
*
|
|
* Description:
|
|
* Move the master node.
|
|
*
|
|
* Input Parameters:
|
|
* sb - Superblock instance of the device.
|
|
* root - New location of the root of the file system.
|
|
* root_sz - New size of the CTZ list of the root of the file syste.
|
|
*
|
|
* Returned Value:
|
|
* 0 - OK
|
|
* < 0 - Error
|
|
*
|
|
* Assumptions/Limitations:
|
|
* This is called when the root is updated to a new location.
|
|
*
|
|
****************************************************************************/
|
|
|
|
int mfs_mn_move(FAR struct mfs_sb_s * const sb, struct mfs_ctz_s root,
|
|
const mfs_t root_sz);
|
|
|
|
int mfs_mn_sync(FAR struct mfs_sb_s *sb,
|
|
FAR struct mfs_path_s * const new_loc,
|
|
const mfs_t blk1, const mfs_t blk2, const mfs_t jrnl_blk);
|
|
|
|
/* mnemofs_fsobj.c */
|
|
|
|
/****************************************************************************
|
|
* Name: mfs_path2childname
|
|
*
|
|
* Description:
|
|
* Given a path, point to the start of the name of the last fs object in
|
|
* that path (child).
|
|
*
|
|
* Input Parameters:
|
|
* relpath - Path.
|
|
*
|
|
* Returned Value:
|
|
* The pointer pointing to where the name of the child starts.
|
|
*
|
|
* Assumptions/Limitations:
|
|
* This does not allocate a new array for the name, but rather just points
|
|
* to the place in `relpath` where the name starts.
|
|
*
|
|
****************************************************************************/
|
|
|
|
FAR const char * mfs_path2childname(FAR const char *relpath);
|
|
|
|
/****************************************************************************
|
|
* Name: mfs_get_fsz
|
|
*
|
|
* Description:
|
|
* Get updated file size of a file.
|
|
*
|
|
* Input Parameters:
|
|
* sb - Superblock instance of the device.
|
|
* path - CTZ representation of the path.
|
|
* depth - Depth of the path.
|
|
*
|
|
* Returned Value:
|
|
* The size of the file.
|
|
*
|
|
****************************************************************************/
|
|
|
|
mfs_t mfs_get_fsz(FAR struct mfs_sb_s * const sb,
|
|
FAR const struct mfs_path_s * const path,
|
|
const mfs_t depth);
|
|
|
|
/****************************************************************************
|
|
* Name: mfs_get_patharr
|
|
*
|
|
* Description:
|
|
* Takes a relpath, and returns the CTZ location of every file system
|
|
* object that occurs in the relpath. This also returns a bit flag
|
|
* consisting of items from `MFS_PATH_FLAGS`.
|
|
*
|
|
* Input Parameters:
|
|
* sb - Superblock instance of the device.
|
|
* relpath - Path of the file.
|
|
* path - To populate with CTZ representation of the path.
|
|
* depth - To populate with depth of the path.
|
|
*
|
|
* Returned Value:
|
|
* 0 - OK
|
|
* < - Error
|
|
*
|
|
* Assumptions/Limitations:
|
|
* This allocates the `path` array in heap, and transfers the ownership
|
|
* of this array to the caller. It's the caller's reponsibility to use this
|
|
* with `mfs_free_patharr`.
|
|
*
|
|
****************************************************************************/
|
|
|
|
int mfs_get_patharr(FAR const struct mfs_sb_s * const sb,
|
|
FAR const char * relpath, FAR struct mfs_path_s **path,
|
|
FAR mfs_t *depth);
|
|
|
|
/****************************************************************************
|
|
* Name: mfs_free_patharr
|
|
*
|
|
* Description:
|
|
* Frees up a CTZ representation of the relpath.
|
|
*
|
|
* Input Parameters:
|
|
* path - CTZ representation of the relpath.
|
|
*
|
|
****************************************************************************/
|
|
|
|
void mfs_free_patharr(FAR struct mfs_path_s *path);
|
|
|
|
/****************************************************************************
|
|
* Name: mfs_obj_isempty
|
|
*
|
|
* Description:
|
|
* Checks if a fs object is empty by reading its directory entry.
|
|
*
|
|
* Input Parameters:
|
|
* sb - Superblock instance of the device.
|
|
* pitr - Parent iterator pointing to the fs object.
|
|
*
|
|
* Returned Value:
|
|
* Is the file or directory pointer by the direntry empty.
|
|
*
|
|
* Assumptions/Limitations:
|
|
* The `pitr` should point to the fs object being checked.
|
|
*
|
|
****************************************************************************/
|
|
|
|
bool mfs_obj_isempty(FAR struct mfs_sb_s * const sb,
|
|
FAR struct mfs_path_s *path,
|
|
FAR struct mfs_pitr_s * const pitr);
|
|
|
|
/****************************************************************************
|
|
* Name: mfs_pitr_init
|
|
*
|
|
* Description:
|
|
* Initialize a parent iterator (pitr). This iterator starts at the start
|
|
* of the parent's directory file, and is used to iterate over the
|
|
* directory entries (direntries) the file has.
|
|
*
|
|
* Input Parameters:
|
|
* sb - Superblock instance of the device.
|
|
* path - CTZ representation of the relpath.
|
|
* depth - Depth of CTZ representation of the path.
|
|
* pitr - To initialize Parent iterator.
|
|
* child - If the child exists in the path.
|
|
*
|
|
* Assumptions/Limitations:
|
|
* - The `pitr` should point to the fs object being checked.
|
|
*
|
|
* - If the `child` is set to true, it assumes the child is present in the
|
|
* directory file. If not, it assumes it's not present in the path (due
|
|
* to whatever circumstances like it's not known if the child exists in
|
|
* the parent or not, search in parent file, etc.).
|
|
*
|
|
* - This assumes the pitr is initialized and freed in the same locked
|
|
* context. If, at all, this is not the case, then at the start of every
|
|
* new locked context till it's freed, this needs to be synced.
|
|
*
|
|
* - This also assumes that a CTZ will not change location before the pitr
|
|
* is destroyed. If at all a CTZ changes location, the pitr needs to be
|
|
* updated.
|
|
*
|
|
* - This contains a pitr with all fields set to 0 when it's invalid.
|
|
*
|
|
****************************************************************************/
|
|
|
|
int mfs_pitr_init(FAR const struct mfs_sb_s * const sb,
|
|
FAR const struct mfs_path_s * const path,
|
|
const mfs_t depth, FAR struct mfs_pitr_s * const pitr,
|
|
bool child);
|
|
|
|
/****************************************************************************
|
|
* Name: mfs_pitr_free
|
|
*
|
|
* Description:
|
|
* Free an initialized pitr.
|
|
*
|
|
* Input Parameters:
|
|
* pitr - Parent iterator.
|
|
*
|
|
* Assumptions/Limitations:
|
|
* It's mainly for symbolic purpose, and the only thing it does is make all
|
|
* the members reset to 0.
|
|
*
|
|
****************************************************************************/
|
|
|
|
void mfs_pitr_free(FAR const struct mfs_pitr_s * const pitr);
|
|
|
|
/****************************************************************************
|
|
* Name: mfs_pitr_adv
|
|
*
|
|
* Description:
|
|
* Advance a pitr to the next direntry.
|
|
*
|
|
* Input Parameters:
|
|
* sb - Superblock instance of the device.
|
|
* pitr - Parent iterator.
|
|
*
|
|
* Assumptions/Limitations:
|
|
* This is best used if we have not already read the value of a dirent. If
|
|
* we have, then we do it the `mfs_pitr_adv_dirent` way.
|
|
*
|
|
****************************************************************************/
|
|
|
|
int mfs_pitr_adv(FAR struct mfs_sb_s * const sb,
|
|
FAR struct mfs_path_s *path,
|
|
FAR struct mfs_pitr_s * const pitr);
|
|
|
|
/****************************************************************************
|
|
* Name: mfs_pitr_adv_bydirent
|
|
*
|
|
* Description:
|
|
* Advance a pitr to the next direntry by using current direntry.
|
|
*
|
|
* Input Parameters:
|
|
* pitr - Parent iterator.
|
|
* dirent - Current directory entry.
|
|
*
|
|
* Assumptions/Limitations:
|
|
* This is best used if we have already got the dirent by which we want to
|
|
* advance entry (the one pointed by pitr). If we don't, then we do it the
|
|
* `mfs_pitr_adv` way.
|
|
*
|
|
****************************************************************************/
|
|
|
|
void mfs_pitr_adv_bydirent(FAR struct mfs_pitr_s * const pitr,
|
|
FAR const struct mfs_dirent_s * const dirent);
|
|
|
|
/****************************************************************************
|
|
* Name: mfs_pitr_adv_off
|
|
*
|
|
* Description:
|
|
* Advance a pitr by an offset.
|
|
*
|
|
* Input Parameters:
|
|
* pitr - Parent iterator.
|
|
*
|
|
* Assumptions/Limitations:
|
|
* This is best used if we have already got the offset by which we want to
|
|
* advance entry. This assumes that once the offset is applied, the new
|
|
* pitr location is valid, and start of a direntry.
|
|
*
|
|
****************************************************************************/
|
|
|
|
void mfs_pitr_adv_off(FAR struct mfs_pitr_s * const pitr,
|
|
const mfs_t off);
|
|
|
|
/****************************************************************************
|
|
* Name: mfs_pitr_adv_tochild
|
|
*
|
|
* Description:
|
|
* Advance the pitr to point to the child mentioned in the path.
|
|
*
|
|
* Input Parameters:
|
|
* pitr - Parent iterator.
|
|
* path - CTZ representation of the relpath
|
|
*
|
|
* Assumptions/Limitations:
|
|
* This assumes that the pitr is initialized for the immediate parent of the
|
|
* child.
|
|
*
|
|
****************************************************************************/
|
|
|
|
void mfs_pitr_adv_tochild(FAR struct mfs_pitr_s * const pitr,
|
|
FAR const struct mfs_path_s * const path);
|
|
|
|
/****************************************************************************
|
|
* Name: mfs_pitr_reset
|
|
*
|
|
* Description:
|
|
* Reset a pitr to point to the start of the CTZ file.
|
|
*
|
|
* Input Parameters:
|
|
* pitr - Parent iterator.
|
|
*
|
|
****************************************************************************/
|
|
|
|
void mfs_pitr_reset(FAR struct mfs_pitr_s * const pitr);
|
|
|
|
/****************************************************************************
|
|
* Name: mfs_pitr_readdirent
|
|
*
|
|
* Description:
|
|
* Reads the direntry pointed to by the pitr.
|
|
*
|
|
* Input Parameters:
|
|
* sb - Superblock instance of the device.
|
|
* pitr - Parent Iterator.
|
|
* dirent - Direntry to populate.
|
|
*
|
|
* Returned Value:
|
|
* Length of the name of the FS object in the direntry.
|
|
*
|
|
* Assumptions/Limitations:
|
|
* This alloctes `dirent`, and transfers the ownership to the caller. It's
|
|
* the caller's responsibility to get it freed using mfs_free_dirent.
|
|
*
|
|
****************************************************************************/
|
|
|
|
int mfs_pitr_readdirent(FAR const struct mfs_sb_s * const sb,
|
|
FAR struct mfs_path_s *path,
|
|
FAR struct mfs_pitr_s * const pitr,
|
|
FAR struct mfs_dirent_s **dirent);
|
|
|
|
/****************************************************************************
|
|
* Name: mfs_pitr_readdirent
|
|
*
|
|
* Description:
|
|
* Free an allocated direntry.
|
|
*
|
|
* Input Parameters:
|
|
* dirent - Direntry.
|
|
*
|
|
****************************************************************************/
|
|
|
|
void mfs_free_dirent(FAR struct mfs_dirent_s *dirent);
|
|
|
|
/****************************************************************************
|
|
* Name: mfs_searchfopen
|
|
*
|
|
* Description:
|
|
* Checks if a file is already open.
|
|
*
|
|
* In mnemofs, this is done by iterating through the kernel list of open
|
|
* files.
|
|
*
|
|
* Input Parameters:
|
|
* sb - Superblock instance of the device.
|
|
* path - CTZ representation of the relpath.
|
|
* depth - Depth of path.
|
|
*
|
|
* Returned Value:
|
|
* True - File is already open.
|
|
* False - File is not open.
|
|
*
|
|
****************************************************************************/
|
|
|
|
bool mfs_searchfopen(FAR const struct mfs_sb_s * const sb,
|
|
FAR const struct mfs_path_s * const path,
|
|
const mfs_t depth);
|
|
|
|
/****************************************************************************
|
|
* Name: mfs_pitr_appenddirent
|
|
*
|
|
* Description:
|
|
* Appeend a direntry at the end of the directory file of parent that's
|
|
* initialized in pitr.
|
|
*
|
|
* In mnemofs, this is done by iterating through the kernel list of open
|
|
* files.
|
|
*
|
|
* Input Parameters:
|
|
* sb - Superblock instance of the device.
|
|
* path - CTZ representation of the relpath.
|
|
* depth - Depth of path.
|
|
* pitr - Parent Iterator.
|
|
* dirent - Directory entry to be added.
|
|
*
|
|
* Returned Value:
|
|
* 0 - OK
|
|
* < 0 - Error
|
|
*
|
|
****************************************************************************/
|
|
|
|
int mfs_pitr_appenddirent(FAR struct mfs_sb_s * const sb,
|
|
FAR struct mfs_path_s * const path,
|
|
const mfs_t depth,
|
|
FAR struct mfs_pitr_s * const pitr,
|
|
FAR const struct mfs_dirent_s * const dirent);
|
|
|
|
/****************************************************************************
|
|
* Name: mfs_pitr_appendnew
|
|
*
|
|
* Description:
|
|
* Appeend a new entry at the end of the directory file of parent that's
|
|
* initialized in pitr. This creates the direntry.
|
|
*
|
|
* Input Parameters:
|
|
* sb - Superblock instance of the device.
|
|
* path - CTZ representation of the relpath.
|
|
* depth - Depth of path.
|
|
* pitr - Parent Iterator.
|
|
* relpath - Relative path of the fs object.
|
|
* mode - Mode of the file/directory.
|
|
*
|
|
* Returned Value:
|
|
* 0 - OK
|
|
* < 0 - Error
|
|
*
|
|
* Assumptions/Limitations:
|
|
* This assumes that the fs object desired to be appended appears at the
|
|
* end of the entire relpath.
|
|
*
|
|
****************************************************************************/
|
|
|
|
int mfs_pitr_appendnew(FAR struct mfs_sb_s * const sb,
|
|
FAR struct mfs_path_s * const path, const mfs_t depth,
|
|
FAR struct mfs_pitr_s * const pitr,
|
|
FAR const char * const relpath, const mode_t mode);
|
|
|
|
/****************************************************************************
|
|
* Name: mfs_pitr_rmdirent
|
|
*
|
|
* Description:
|
|
* Removes the dirent from its parent's directory file.
|
|
*
|
|
* Input Parameters:
|
|
* sb - Superblock instance of the device.
|
|
* path - CTZ representation of the relpath.
|
|
* depth - Depth of path.
|
|
* pitr - Parent Iterator.
|
|
* dirent - Directory entry to be added.
|
|
*
|
|
* Returned Value:
|
|
* 0 - OK
|
|
* < 0 - Error
|
|
*
|
|
****************************************************************************/
|
|
|
|
int mfs_pitr_rmdirent(FAR struct mfs_sb_s * const sb,
|
|
FAR struct mfs_path_s * const path,
|
|
const mfs_t depth, FAR struct mfs_pitr_s * const pitr,
|
|
FAR const struct mfs_dirent_s * const dirent);
|
|
|
|
/****************************************************************************
|
|
* Name: mfs_pitr_rm
|
|
*
|
|
* Description:
|
|
* Removes the fs object pointed by path from its parent's directory file.
|
|
*
|
|
* Input Parameters:
|
|
* sb - Superblock instance of the device.
|
|
* path - CTZ representation of the relpath.
|
|
* depth - Depth of path.
|
|
*
|
|
* Returned Value:
|
|
* 0 - OK
|
|
* < 0 - Error
|
|
*
|
|
* Assumptions/Limitations:
|
|
* This does not require any form of pitr initialization. It does it inside
|
|
* itself.
|
|
*
|
|
****************************************************************************/
|
|
|
|
int mfs_pitr_rm(FAR struct mfs_sb_s * const sb,
|
|
FAR struct mfs_path_s * const path,
|
|
const mfs_t depth, bool rm_child);
|
|
|
|
int mfs_pitr_traversefs(FAR struct mfs_sb_s * sb, const struct mfs_ctz_s ctz,
|
|
int type);
|
|
|
|
#undef EXTERN
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif /* __FS_MNEMOFS_MNEMOFS_H */
|