/*-
* Copyright (c) 2010-2012 Semihalf.
* All rights reserved.
*
* 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
*
* 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.
*/
__FBSDID("$FreeBSD$");
#include "stand.h"
#include "string.h"
#include "zlib.h"
#define DEBUG
#ifdef DEBUG
#else
#endif
struct nandfs_mdt {
};
struct bmap_buf {
};
struct nandfs_node {
};
struct nandfs {
int nf_blocksize;
int nf_sectorsize;
int nf_cpno;
};
static int nandfs_open(const char *, struct open_file *);
static int nandfs_close(struct open_file *);
nandfs_lbn_t, u_int, void *, int);
nandfs_lbn_t, nandfs_daddr_t *, int);
struct nandfs_checkpoint *);
static void nandfs_calc_mdt_consts(int, struct nandfs_mdt *, int);
nandfs_daddr_t *, uint32_t *);
static int nandfs_probe_sectorsize(struct open_file *);
"nandfs",
};
/* from NetBSD's src/sys/net/if_ethersubr.c */
static uint32_t
{
0x00000000, 0x1db71064, 0x3b6e20c8, 0x26d930ac,
0x76dc4190, 0x6b6b51f4, 0x4db26158, 0x5005713c,
0xedb88320, 0xf00f9344, 0xd6d6a3e8, 0xcb61b38c,
0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c
};
size_t i;
for (i = 0; i < len; i++) {
}
return (crc ^ ~0U);
}
static int
{
return (0);
/* Preserve crc */
/* Calculate */
/* Restore */
/* Check CRC */
return (fsdata_crc == comp_crc);
}
static int
struct nandfs_super_block *super)
{
/* Check super block magic */
return (0);
/* Preserve CRC */
/* Calculate */
/* Restore */
/* Check CRC */
}
static int
{
int i, j, n, s;
return (ENOMEM);
for (i = 0; i < sectors_to_read; i++) {
NANDFS_DEBUG("reading i %d offset %d\n", i,
i * fs->nf_sectorsize);
fs->nf_sectorsize);
if (error) {
continue;
}
s = 0;
continue;
else {
s += (sizeof(struct nandfs_fsdata) /
sizeof(struct nandfs_super_block));
}
}
for (j = s; j < n; j++) {
continue;
NANDFS_DEBUG("magic %x wtime %jd, lastcp 0x%jx\n",
}
}
}
static int
{
NANDFS_DEBUG("starting\n");
offset = 0;
for (i = 0; i < 64 * NANDFS_NFSAREAS; i++) {
sizeof(struct nandfs_fsdata));
if (error)
return (error);
break;
}
}
return (error);
}
static int
{
int error;
if (error)
return (error);
if (error == 0)
NANDFS_DEBUG("selected sb with w_time %jd last_pseg %jx\n",
return (error);
}
static int
{
if (err) {
return (err);
}
/*
* Calculate indirect block levels.
*/
mult = 1;
}
sizeof(struct nandfs_segment_summary));
if (err) {
return (err);
}
if (err) {
return (err);
}
if (err) {
return (err);
}
NANDFS_DEBUG("checkpoint cp_inodes_count=%lld\n",
NANDFS_DEBUG("checkpoint cp_ifile_inode.i_blocks=%lld\n",
return (0);
}
static int
{
bsize = nandfs_probe_sectorsize(f);
if (bsize < 0) {
printf("Cannot probe medium sector size\n");
return (EINVAL);
}
/*
* Calculate indirect block levels.
*/
mult = 1;
}
if (err) {
return (err);
}
return (EINVAL);
return (0);
}
static void
{
}
}
static int
{
NANDFS_DEBUG("nandfs_close(%p)\n", f);
return (0);
}
static int
{
void *buf;
int error = 0;
while (size != 0) {
break;
if (error)
break;
}
if (resid)
return (error);
}
static off_t
{
NANDFS_DEBUG("nandfs_seek(file=%p, offset=%lld, where=%d)\n", f,
switch (where) {
case SEEK_SET:
off = 0;
break;
case SEEK_CUR:
break;
case SEEK_END:
break;
default:
return (-1);
}
return(-1);
}
return (off);
}
static int
{
return (0);
}
static int
{
void *buf;
NANDFS_DEBUG("nandfs_readdir(file=%p, dirent=%p)\n", f, d);
NANDFS_DEBUG("nandfs_readdir(file=%p, dirent=%p) ENOENT\n",
f, d);
return (ENOENT);
}
NANDFS_DEBUG("nandfs_readdir(file=%p, dirent=%p)"
"buf_read failed\n", f, d);
return (EIO);
}
NANDFS_DEBUG("nandfs_readdir(file=%p, dirent=%p) moving forward\n",
f, d);
return (0);
}
static int
{
return (EIO);
}
return (0);
}
static struct nandfs_node *
{
int entrynr;
if (ino == 0) {
printf("nandfs_lookup_node: invalid inode requested\n");
return (NULL);
}
return (NULL);
return (node);
}
static struct nandfs_node *
{
char *namebuf;
/* Get the root inode */
if (*strp == '\0')
continue;
goto out;
}
goto out;
}
while (1) {
dirent =
(struct nandfs_dir_entry *)(void *)buffer;
NANDFS_DEBUG("%s: dirent.name = %s\n",
NANDFS_DEBUG("%s: dirent.rec_len = %d\n",
NANDFS_DEBUG("%s: dirent.inode = %lld\n",
done = 1;
break;
}
break;
}
if (done)
break;
}
if (!done) {
goto out;
}
NANDFS_DEBUG("%s: %.*s is symlink\n",
if (++nlinks > MAXSYMLINKS) {
goto out;
}
goto out;
}
NANDFS_DEBUG("%s: symlink is %.*s\n",
(unsigned)link_len);
MAXPATHLEN - link_len);
} else
NANDFS_DEBUG("%s: strp=%s, lpath=%s, namebuf0=%s, "
/*
* If absolute pathname, restart at root. Otherwise
* continue with out parent inode.
*/
}
}
out:
return (node);
}
static int
{
u_int i;
int error;
NANDFS_DEBUG("nandfs_read_inode fs=%p node=%p blknr=%lld nblks=%d\n",
for (i = 0; i < nblks; i++) {
if (error) {
return (error);
}
if (raw == 0)
else
}
for (i = 0; i < nblks; i++) {
fs->nf_blocksize)) {
return (EIO);
}
}
return (0);
}
static int
{
fs->nf_blocksize));
}
static int
struct nandfs_checkpoint *cp)
{
return (EINVAL);
}
return (0);
}
static uint64_t *
int phys)
{
}
return (NULL);
}
return (map);
}
static int
{
int idx;
int level;
return (0);
}
/*
* nindir[0] = NINDIR
* nindir[1] = NINDIR**2
* nindir[2] = NINDIR**3
* etc
*/
break;
}
/* Block number too high */
return (EFBIG);
}
if (ind_block_num == 0) {
*vblknr = 0; /* missing */
return (0);
}
twiddle(1);
return (EIO);
if (level > 0) {
} else
}
*vblknr = ind_block_num;
return (0);
}
static nandfs_daddr_t
{
int entrynr;
return (0);
}
NANDFS_DEBUG("nandfs_vtop entrynr=%d vblocknr=%lld pblocknr=%lld\n",
return (pblocknr);
}
static void
{
blocksize / sizeof(struct nandfs_block_group_desc);
}
static void
{
/* Calculate our offset in the file */
/* To descgroup offset */
/* To group offset */
/* To actual file block */
}
static int
{
void *buffer;
int err;
return (err);
}
static int
{
void *buffer;
int i, err;
NANDFS_DEBUG("probing for sector size: ");
for (i = 512; i < (16 * 1024); i <<= 1) {
NANDFS_DEBUG("%d ", i);
if (err == 0) {
NANDFS_DEBUG("found");
return (i);
}
}
NANDFS_DEBUG("not found\n");
return (-1);
}