nuttx/fs/mnemofs/mnemofs.h
Saurav Pal 23b7dc0651 fs/mnemofs: Setup and VFS methods
The Setup and VFS methods for mnemofs, a NAND Flash File System.

Signed-off-by: Saurav Pal <resyfer.dev@gmail.com>
2024-07-10 09:25:23 -03:00

1107 lines
34 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_NPGS(sb) (MFS_NBLKS(sb) * MFS_PGINBLK(sb))
#define MFS_CTZ_SZ(l) ((l)->sz)
#define MFS_DIRENTSZ(dirent) (sizeof(struct mfs_dirent_s) \
+ (dirent)->namelen)
/****************************************************************************
* 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_NEXIST = (1 << 2), /* Path No Exist */
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;
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;
};
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;
mfs_t n_lru;
uint16_t pg_in_blk;
uint8_t log_pg_in_blk;
uint8_t j_nblks;
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. */
};
/* 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;
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
{
uint8_t name_hash; /* Should be at start to improve efficiency. */
mfs_t sz;
uint16_t mode;
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. */
mfs_t sz; /* Parent's size. */
};
/****************************************************************************
* 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_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);
/****************************************************************************
* 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);
/* mnemofs_blkalloc.c */
/****************************************************************************
* 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_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);
/****************************************************************************
* 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);
/* mnemofs_rw.c */
/****************************************************************************
* 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);
/* mnemofs_lru.c */
/****************************************************************************
* 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.
* ctz_sz - Number of bytes in the data of the CTZ list.
* path - CTZ representation of the relpath.
* depth - Depth of path.
*
****************************************************************************/
int mfs_lru_del(FAR struct mfs_sb_s * const sb, const mfs_t off,
mfs_t bytes, mfs_t ctz_sz,
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.
* ctz_sz - Number of bytes in the data of the CTZ list.
* 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, mfs_t ctz_sz, FAR struct mfs_path_s * const path,
const mfs_t depth, FAR const char *buf);
/****************************************************************************
* 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.
* ctz_sz - Size of the CTZ file.
*
****************************************************************************/
int mfs_lru_ctzflush(FAR struct mfs_sb_s * const sb,
FAR struct mfs_path_s * const path, const mfs_t depth,
const mfs_t ctz_sz);
/****************************************************************************
* 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 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_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_updatedsz
*
* Description:
* Update size of a CTZ list.
*
* Input Parameters:
* sb - Superblock instance of the device.
* path - CTZ representation of the relpath.
* depth - Depth of path.
* n_sz - New size.
*
****************************************************************************/
void mfs_lru_updatedsz(FAR struct mfs_sb_s * const sb,
FAR const struct mfs_path_s * const path,
const mfs_t depth, mfs_t *n_sz);
/* 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 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_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.
*
****************************************************************************/
void mfs_pitr_init(FAR struct mfs_sb_s * const sb,
FAR const struct mfs_path_s * const path,
const mfs_t depth, FAR struct mfs_pitr_s *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 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.
*
****************************************************************************/
void mfs_pitr_adv(FAR struct mfs_sb_s * const sb,
FAR struct mfs_pitr_s * const pitr);
/****************************************************************************
* Name: mfs_pitr_adv_dirent
*
* 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_dirent(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
* depth - Depth of path.
*
* 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,
const mfs_t depth);
/****************************************************************************
* 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_sync
*
* Description:
* Sync a pitr.
*
* In mnemofs, when moving between locked contexts, it may happen that a
* a CTZ is moved to some place is between. This updates the location by
* reading the journal to check for any related logs in the journal.
* Updates contained in the LRU do not update the location of a CTZ list.
*
* Input Parameters:
* sb - Superblock instance of the device.
* pitr - Parent iterator.
* path - CTZ representation of the relpath
* depth - Depth of path.
*
****************************************************************************/
void mfs_pitr_sync(FAR struct mfs_sb_s * const sb,
FAR struct mfs_pitr_s * const pitr,
FAR const struct mfs_path_s * const path,
const mfs_t depth);
/****************************************************************************
* 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 struct mfs_sb_s * const sb,
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 const 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.
* dirent - Directory entry to be added.
* mode - Mode of the file/directory.
*
* Returned Value:
* 0 - OK
* < 0 - Error
*
****************************************************************************/
int mfs_pitr_appendnew(FAR struct mfs_sb_s * const sb,
FAR struct mfs_path_s * const path,
const mfs_t depth,
FAR const struct mfs_pitr_s * const pitr,
FAR const char * const child_name, 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);
#undef EXTERN
#ifdef __cplusplus
}
#endif
#endif /* __FS_MNEMOFS_MNEMOFS_H */