svn commit: r235182 - in projects/nand: lib/libnandfs lib/libstand
sbin/nandfs sbin/newfs_nandfs sys/fs/nandfs
Grzegorz Bernacki
gber at FreeBSD.org
Wed May 9 14:52:03 UTC 2012
Author: gber
Date: Wed May 9 14:52:03 2012
New Revision: 235182
URL: http://svn.freebsd.org/changeset/base/235182
Log:
nandfs: Various fixes and cleanup.
- get rid of crc32_le, use existing implementations instead
- bump nandfs version number
- properly calculate dat block number
- properly iterate over dirty segments
- fix rec_len calculation in make_dir()
- prevent write access to bad blocks
- don't create ".nandfs" in root folder of nandfs partition
- make sure that syncer is run after cleaner exit and after vflush
- fix assert condition about pblocknr
- rewrite locking for syncer
- provide dedicated vnode ops for system vnodes
- enable cleaner by default
Obtained from: Semihalf
Supported by: FreeBSD Foundation, Juniper Networks
Modified:
projects/nand/lib/libnandfs/nandfs.c
projects/nand/lib/libstand/nandfs.c
projects/nand/sbin/nandfs/nandfs.c
projects/nand/sbin/newfs_nandfs/newfs_nandfs.c
projects/nand/sys/fs/nandfs/bmap.c
projects/nand/sys/fs/nandfs/nandfs.h
projects/nand/sys/fs/nandfs/nandfs_alloc.c
projects/nand/sys/fs/nandfs/nandfs_bmap.c
projects/nand/sys/fs/nandfs/nandfs_cleaner.c
projects/nand/sys/fs/nandfs/nandfs_cpfile.c
projects/nand/sys/fs/nandfs/nandfs_dat.c
projects/nand/sys/fs/nandfs/nandfs_fs.h
projects/nand/sys/fs/nandfs/nandfs_segment.c
projects/nand/sys/fs/nandfs/nandfs_subr.c
projects/nand/sys/fs/nandfs/nandfs_subr.h
projects/nand/sys/fs/nandfs/nandfs_sufile.c
projects/nand/sys/fs/nandfs/nandfs_vfsops.c
projects/nand/sys/fs/nandfs/nandfs_vnops.c
Modified: projects/nand/lib/libnandfs/nandfs.c
==============================================================================
--- projects/nand/lib/libnandfs/nandfs.c Wed May 9 14:51:07 2012 (r235181)
+++ projects/nand/lib/libnandfs/nandfs.c Wed May 9 14:52:03 2012 (r235182)
@@ -108,7 +108,7 @@ void
nandfs_init(struct nandfs *fs, const char *dir)
{
- snprintf(fs->n_ioc, sizeof(fs->n_ioc), "%s/%s", dir, ".nandfs");
+ snprintf(fs->n_ioc, sizeof(fs->n_ioc), "%s/%s", dir, ".");
fs->n_iocfd = -1;
fs->n_flags = NANDFS_IS_VALID;
}
Modified: projects/nand/lib/libstand/nandfs.c
==============================================================================
--- projects/nand/lib/libstand/nandfs.c Wed May 9 14:51:07 2012 (r235181)
+++ projects/nand/lib/libstand/nandfs.c Wed May 9 14:52:03 2012 (r235182)
@@ -34,6 +34,7 @@ __FBSDID("$FreeBSD$");
#include <fs/nandfs/nandfs_fs.h>
#include "stand.h"
#include "string.h"
+#include "zlib.h"
#define DEBUG
#undef DEBUG
@@ -124,27 +125,6 @@ struct fs_ops nandfs_fsops = {
#define NINDIR(fs) ((fs)->nf_blocksize / sizeof(nandfs_daddr_t))
-/* from NetBSD's src/sys/net/if_ethersubr.c */
-static uint32_t
-crc32_le(uint32_t crc, const uint8_t *buf, size_t len)
-{
- static const uint32_t crctab[] = {
- 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++) {
- crc ^= buf[i];
- crc = (crc >> 4) ^ crctab[crc & 0xf];
- crc = (crc >> 4) ^ crctab[crc & 0xf];
- }
-
- return (crc);
-}
-
static int
nandfs_check_fsdata_crc(struct nandfs_fsdata *fsdata)
{
@@ -158,8 +138,7 @@ nandfs_check_fsdata_crc(struct nandfs_fs
/* Calculate */
fsdata->f_sum = (0);
- comp_crc = crc32_le(fsdata->f_crc_seed, (uint8_t *) fsdata,
- fsdata->f_bytes);
+ comp_crc = crc32(0, (uint8_t *)fsdata, fsdata->f_bytes);
/* Restore */
fsdata->f_sum = fsdata_crc;
@@ -183,8 +162,7 @@ nandfs_check_superblock_crc(struct nandf
/* Calculate */
super->s_sum = (0);
- comp_crc = crc32_le(fsdata->f_crc_seed, (uint8_t *) super,
- fsdata->f_sbbytes);
+ comp_crc = crc32(0, (uint8_t *)super, fsdata->f_sbbytes);
/* Restore */
super->s_sum = super_crc;
@@ -983,7 +961,7 @@ nandfs_calc_mdt_consts(int blocksize, st
static void
nandfs_mdt_trans(struct nandfs_mdt *mdt, uint64_t index,
- nandfs_daddr_t *blocknr, uint32_t *entry_in_block)
+ nandfs_daddr_t *blocknr, uint32_t *entry_in_block)
{
nandfs_daddr_t blknr;
uint64_t group, group_offset, blocknr_in_group;
Modified: projects/nand/sbin/nandfs/nandfs.c
==============================================================================
--- projects/nand/sbin/nandfs/nandfs.c Wed May 9 14:51:07 2012 (r235181)
+++ projects/nand/sbin/nandfs/nandfs.c Wed May 9 14:52:03 2012 (r235182)
@@ -43,7 +43,7 @@ static void
usage(void)
{
- fprintf(stderr, "usage: nandfs [lssnap | mksnap <snap> | rmsnap] "
+ fprintf(stderr, "usage: nandfs [lssnap | mksnap | rmsnap <snap>] "
"node\n");
exit(1);
}
Modified: projects/nand/sbin/newfs_nandfs/newfs_nandfs.c
==============================================================================
--- projects/nand/sbin/newfs_nandfs/newfs_nandfs.c Wed May 9 14:51:07 2012 (r235181)
+++ projects/nand/sbin/newfs_nandfs/newfs_nandfs.c Wed May 9 14:52:03 2012 (r235182)
@@ -67,6 +67,8 @@ __FBSDID("$FreeBSD$");
#define NANDFS_FIRST_BLOCK nandfs_first_block()
#define NANDFS_FIRST_CNO 1
+#define NANDFS_BLOCK_BAD 1
+#define NANDFS_BLOCK_GOOD 0
struct file_info {
uint64_t ino;
@@ -80,8 +82,7 @@ struct file_info {
struct file_info user_files[] =
{
- {NANDFS_ROOT_INO, NULL, S_IFDIR | 0755, 0, 1, NULL, NULL},
- {NANDFS_USER_INO, ".nandfs", S_IFREG | 0644, 0, 0, NULL, NULL},
+ {NANDFS_ROOT_INO, NULL, S_IFDIR | 0755, 0, 1, NULL, NULL},
};
struct file_info ifile = {NANDFS_IFILE_INO, NULL, 0, 0, -1, NULL, NULL};
@@ -117,9 +118,9 @@ static long rsv_segment_percent = 5;
static time_t nandfs_time;
static uint32_t bad_segments_count = 0;
static uint32_t *bad_segments = NULL;
+static uint8_t fsdata_blocks_state[NANDFS_NFSAREAS];
u_char *volumelabel = NULL;
-uint32_t crc_seed;
struct nandfs_super_root *sr;
@@ -133,9 +134,18 @@ uint32_t seg_endblock;
static uint32_t
nandfs_first_block(void)
{
- uint32_t first_free;
+ uint32_t i, first_free, start_bad_segments = 0;
+
+ for (i = 0; i < bad_segments_count; i++) {
+ if (i == bad_segments[i])
+ start_bad_segments++;
+ else
+ break;
+ }
+
+ first_free = SIZE_TO_BLOCK(NANDFS_DATA_OFFSET_BYTES(erasesize) +
+ (start_bad_segments * segsize));
- first_free = (uint32_t)(NANDFS_DATA_OFFSET_BYTES(erasesize)/blocksize);
if (first_free < (uint32_t)blocks_per_segment)
return (blocks_per_segment);
else
@@ -181,13 +191,15 @@ crc32_le(uint32_t crc, const uint8_t *bu
};
size_t i;
+ crc = crc ^ ~0U;
+
for (i = 0; i < len; i++) {
crc ^= buf[i];
crc = (crc >> 4) ^ crctab[crc & 0xf];
crc = (crc >> 4) ^ crctab[crc & 0xf];
}
- return (crc);
+ return (crc ^ ~0U);
}
static void *
@@ -466,7 +478,7 @@ save_segsum(struct nandfs_segment_summar
ss->ss_sumbytes = sum_bytes;
crc_skip = sizeof(ss->ss_datasum) + sizeof(ss->ss_sumsum);
- ss->ss_sumsum = crc32_le(crc_seed, (uint8_t *)ss + crc_skip,
+ ss->ss_sumsum = crc32_le(0, (uint8_t *)ss + crc_skip,
sum_bytes - crc_skip);
crc_data = 0;
@@ -483,7 +495,7 @@ save_segsum(struct nandfs_segment_summar
/* save superroot crc */
crc_skip = sizeof(sr->sr_sum);
- sr->sr_sum = crc32_le(crc_seed, (uint8_t *)sr + crc_skip,
+ sr->sr_sum = crc32_le(0, (uint8_t *)sr + crc_skip,
NANDFS_SR_BYTES - crc_skip);
/* segment checksup */
@@ -492,11 +504,12 @@ save_segsum(struct nandfs_segment_summar
if (block->number < NANDFS_FIRST_BLOCK)
continue;
if (block->number == NANDFS_FIRST_BLOCK)
- crc_data = crc32_le(crc_seed,
+ crc_data = crc32_le(0,
(uint8_t *)block->data + crc_skip,
blocksize - crc_skip);
else
- crc_data = crc32_le(crc_data, block->data, blocksize);
+ crc_data = crc32_le(crc_data, (uint8_t *)block->data,
+ blocksize);
}
ss->ss_datasum = crc_data;
}
@@ -513,7 +526,6 @@ create_fsdata(void)
fsdata.f_first_data_block = NANDFS_FIRST_BLOCK;
fsdata.f_blocks_per_segment = blocks_per_segment;
fsdata.f_r_segments_percentage = rsv_segment_percent;
- fsdata.f_crc_seed = crc_seed;
fsdata.f_rev_level = NANDFS_CURRENT_REV;
fsdata.f_sbbytes = NANDFS_SB_BYTES;
fsdata.f_bytes = NANDFS_FSDATA_CRC_BYTES;
@@ -530,7 +542,7 @@ create_fsdata(void)
if (volumelabel)
memcpy(fsdata.f_volume_name, volumelabel, 16);
- fsdata.f_sum = crc32_le(crc_seed, (const uint8_t *)&fsdata,
+ fsdata.f_sum = crc32_le(0, (const uint8_t *)&fsdata,
NANDFS_FSDATA_CRC_BYTES);
}
@@ -552,12 +564,12 @@ create_super_block(void)
super_block.s_last_pseg = NANDFS_FIRST_BLOCK;
super_block.s_last_seq = 1;
super_block.s_free_blocks_count =
- (nsegments - bad_segments_count) * blocks_per_segment;
+ (nsegments - bad_segments_count) * blocks_per_segment;
super_block.s_mtime = 0;
super_block.s_wtime = nandfs_time;
super_block.s_state = NANDFS_VALID_FS;
- super_block.s_sum = crc32_le(crc_seed, (const uint8_t *)&super_block,
+ super_block.s_sum = crc32_le(0, (const uint8_t *)&super_block,
NANDFS_SB_BYTES);
}
@@ -617,16 +629,17 @@ make_dir(void *block, uint64_t ino, uint
de->rec_len = NANDFS_DIR_REC_LEN(2);
de->name_len = 2;
de->file_type = DT_DIR;
- memcpy(de->name, "..\0\0\0\0\0\0", 8);
+ memset(de->name, 0, NANDFS_DIR_NAME_LEN(2));
+ memcpy(de->name, "..", 2);
/* create '.' entry */
de = (void *)((uint8_t *)block + NANDFS_DIR_REC_LEN(2));
de->inode = ino;
- de->rec_len = blocksize - NANDFS_DIR_REC_LEN(1) + NANDFS_DIR_REC_LEN(2);
+ de->rec_len = blocksize - NANDFS_DIR_REC_LEN(2);
de->name_len = 1;
de->file_type = DT_DIR;
- memcpy(de->name, ".\0\0\0\0\0\0\0", 8);
-
+ memset(de->name, 0, NANDFS_DIR_NAME_LEN(1));
+ memcpy(de->name, ".", 1);
return (de);
}
@@ -817,6 +830,9 @@ create_fs(void)
create_super_block();
for (i = 0; i < NANDFS_NFSAREAS; i++) {
+ if (fsdata_blocks_state[i] != NANDFS_BLOCK_GOOD)
+ continue;
+
data = get_block((i * erasesize)/blocksize, 0);
save_fsdata(data);
@@ -899,7 +915,6 @@ check_parameters(void)
}
nandfs_time = time(NULL);
- crc_seed = (uint32_t)mrand48();
}
static void
@@ -1003,8 +1018,10 @@ erase_device(int fd)
debug("Deleting %jx\n", i * erasesize);
if (g_delete(fd, i * erasesize, erasesize)) {
printf("cannot delete %jx\n", i * erasesize);
+ fsdata_blocks_state[i] = NANDFS_BLOCK_BAD;
failed++;
- }
+ } else
+ fsdata_blocks_state[i] = NANDFS_BLOCK_GOOD;
}
if (failed == NANDFS_NFSAREAS) {
Modified: projects/nand/sys/fs/nandfs/bmap.c
==============================================================================
--- projects/nand/sys/fs/nandfs/bmap.c Wed May 9 14:51:07 2012 (r235181)
+++ projects/nand/sys/fs/nandfs/bmap.c Wed May 9 14:52:03 2012 (r235182)
@@ -490,7 +490,7 @@ direct:
nandfs_error("%s: cannot destroy "
"block %jx, error %d\n", __func__,
(uintmax_t)ip->i_db[i], error);
- return (error);
+ return (error);
}
ip->i_db[i] = 0;
}
Modified: projects/nand/sys/fs/nandfs/nandfs.h
==============================================================================
--- projects/nand/sys/fs/nandfs/nandfs.h Wed May 9 14:51:07 2012 (r235181)
+++ projects/nand/sys/fs/nandfs/nandfs.h Wed May 9 14:52:03 2012 (r235182)
@@ -97,6 +97,7 @@ int nandfs_init(struct vfsconf *);
int nandfs_uninit(struct vfsconf *);
extern struct vop_vector nandfs_vnodeops;
+extern struct vop_vector nandfs_system_vnodeops;
struct nandfs_node;
@@ -222,9 +223,8 @@ struct nandfs_device {
extern SLIST_HEAD(_nandfs_devices, nandfs_device) nandfs_devices;
-#define NANDFS_KILL_SYNCER 0x1
-#define NANDFS_FORCE_SYNCER 0x2
-#define NANDFS_UMOUNT 0x4
+#define NANDFS_FORCE_SYNCER 0x1
+#define NANDFS_UMOUNT 0x2
#define SYNCER_UMOUNT 0x0
#define SYNCER_VFS_SYNC 0x1
@@ -233,10 +233,32 @@ extern SLIST_HEAD(_nandfs_devices, nandf
#define SYNCER_FSYNC 0x4
#define SYNCER_ROUPD 0x5
-#define NANDFS_WRITELOCK(vp, fsdev) nandfs_writelock(vp, fsdev)
-#define NANDFS_WRITEUNLOCK(fsdev) nandfs_writeunlock(fsdev)
+static __inline int
+nandfs_writelockflags(struct nandfs_device *fsdev, int flags)
+{
+ int error = 0;
-#define NANDFS_WRITEASSERT(fsdev) nandfs_writeassert(fsdev)
+ if (lockstatus(&fsdev->nd_seg_const) != LK_EXCLUSIVE)
+ error = lockmgr(&fsdev->nd_seg_const, flags | LK_SHARED, NULL);
+
+ return (error);
+}
+
+static __inline void
+nandfs_writeunlock(struct nandfs_device *fsdev)
+{
+
+ if (lockstatus(&fsdev->nd_seg_const) != LK_EXCLUSIVE)
+ lockmgr(&(fsdev)->nd_seg_const, LK_RELEASE, NULL);
+}
+
+#define NANDFS_WRITELOCKFLAGS(fsdev, flags) nandfs_writelockflags(fsdev, flags)
+
+#define NANDFS_WRITELOCK(fsdev) NANDFS_WRITELOCKFLAGS(fsdev, 0)
+
+#define NANDFS_WRITEUNLOCK(fsdev) nandfs_writeunlock(fsdev)
+
+#define NANDFS_WRITEASSERT(fsdev) lockmgr_assert(&(fsdev)->nd_seg_const, KA_LOCKED)
/* Specific mountpoint; head or a checkpoint/snapshot */
struct nandfsmount {
Modified: projects/nand/sys/fs/nandfs/nandfs_alloc.c
==============================================================================
--- projects/nand/sys/fs/nandfs/nandfs_alloc.c Wed May 9 14:51:07 2012 (r235181)
+++ projects/nand/sys/fs/nandfs/nandfs_alloc.c Wed May 9 14:52:03 2012 (r235182)
@@ -286,7 +286,7 @@ nandfs_alloc_entry(struct nandfs_mdt* md
uint32_t *mask, maskrw;
nandfs_calc_idx_entry(mdt, req->entrynum, &group, &bitmap_idx,
- &bitmap_off);
+ &bitmap_off);
DPRINTF(ALLOC, ("nandfs_alloc_entry: req->entrynum=%jx bitmap_idx=%jx"
" bitmap_off=%jx group=%jx\n", (uintmax_t)req->entrynum,
Modified: projects/nand/sys/fs/nandfs/nandfs_bmap.c
==============================================================================
--- projects/nand/sys/fs/nandfs/nandfs_bmap.c Wed May 9 14:51:07 2012 (r235181)
+++ projects/nand/sys/fs/nandfs/nandfs_bmap.c Wed May 9 14:52:03 2012 (r235182)
@@ -73,37 +73,19 @@ int
nandfs_bmap_lookup(struct nandfs_node *node, nandfs_lbn_t lblk,
nandfs_daddr_t *vblk)
{
- int error;
-
- error = bmap_lookup(node, lblk, vblk);
- if (error)
- nandfs_error("%s: returned %d", __func__, error);
-
- return (error);
-}
-
-int
-nandfs_bmap_nlookup(struct nandfs_node *node, nandfs_lbn_t from, uint64_t blks,
- uint64_t *l2vmap)
-{
int error = 0;
- nandfs_lbn_t lblk, *vblk;
-
- MPASS(blks == 1);
- lblk = from;
- vblk = l2vmap;
- if (node->nn_ino == NANDFS_GC_INO && from >= 0)
+ if (node->nn_ino == NANDFS_GC_INO && lblk >= 0)
*vblk = lblk;
else
- error = nandfs_bmap_lookup(node, from, l2vmap);
+ error = bmap_lookup(node, lblk, vblk);
DPRINTF(TRANSLATE, ("%s: error %d ino %#jx lblocknr %#jx -> %#jx\n",
__func__, error, (uintmax_t)node->nn_ino, (uintmax_t)lblk,
(uintmax_t)*vblk));
if (error)
- nandfs_error("%s: return %d", __func__, error);
+ nandfs_error("%s: returned %d", __func__, error);
return (error);
}
Modified: projects/nand/sys/fs/nandfs/nandfs_cleaner.c
==============================================================================
--- projects/nand/sys/fs/nandfs/nandfs_cleaner.c Wed May 9 14:51:07 2012 (r235181)
+++ projects/nand/sys/fs/nandfs/nandfs_cleaner.c Wed May 9 14:52:03 2012 (r235182)
@@ -187,8 +187,13 @@ static int
nandfs_cleaner_bdesc_is_alive(struct nandfs_device *fsdev,
struct nandfs_bdesc *bdesc)
{
+ int alive;
- return (bdesc->bd_oblocknr == bdesc->bd_blocknr);
+ alive = bdesc->bd_oblocknr == bdesc->bd_blocknr;
+ if (!alive)
+ MPASS(abs(bdesc->bd_oblocknr - bdesc->bd_blocknr) > 2);
+
+ return (alive);
}
static void
@@ -213,7 +218,12 @@ nandfs_cleaner_iterate_psegment(struct n
for (i = 0; i < segsum->ss_nbinfos; i++) {
if (binfo[i].bi_v.bi_ino == NANDFS_DAT_INO) {
(*bdpp)->bd_oblocknr = blk + segsum->ss_nblocks -
- segsum->ss_nbinfos + i - 1;
+ segsum->ss_nbinfos + i;
+ /*
+ * XXX Hack
+ */
+ if (segsum->ss_flags & NANDFS_SS_SR)
+ (*bdpp)->bd_oblocknr--;
(*bdpp)->bd_level = binfo[i].bi_dat.bi_level;
(*bdpp)->bd_offset = binfo[i].bi_dat.bi_blkoff;
(*bdpp)++;
@@ -288,9 +298,10 @@ nandfs_cleaner_choose_segment(struct nan
suinfo = malloc(sizeof(*suinfo) * nsegs, M_NANDFSTEMP,
M_ZERO | M_WAITOK);
- if (*rseg >= fsdev->nd_seg_num)
+ if (*rseg >= fsdev->nd_fsdata.f_nsegments)
*rseg = 0;
+retry:
error = nandfs_get_segment_info_filter(fsdev, suinfo, nsegs, *rseg,
&ssegs, NANDFS_SEGMENT_USAGE_DIRTY,
NANDFS_SEGMENT_USAGE_ACTIVE | NANDFS_SEGMENT_USAGE_ERROR |
@@ -300,6 +311,11 @@ nandfs_cleaner_choose_segment(struct nan
goto out;
}
+ if (ssegs == 0 && *rseg != 0) {
+ *rseg = 0;
+ goto retry;
+ }
+
print_suinfo(suinfo, ssegs);
for (i = 0; i < ssegs; i++) {
@@ -392,7 +408,8 @@ nandfs_cleaner_body(struct nandfs_device
}
}
- lockmgr(&fsdev->nd_seg_const, LK_EXCLUSIVE, NULL);
+ NANDFS_WRITELOCK(fsdev);
+ DPRINTF(CLEAN, ("%s: got lock\n", __func__));
error = nandfs_get_dat_vinfo(fsdev, vinfo, vip - vinfo);
if (error) {
@@ -430,7 +447,7 @@ nandfs_cleaner_body(struct nandfs_device
nandfs_error("%s:%d\n", __FILE__, __LINE__);
out_locked:
- lockmgr(&fsdev->nd_seg_const, LK_RELEASE, NULL);
+ NANDFS_WRITEUNLOCK(fsdev);
out:
free(cpinfo, M_NANDFSTEMP);
free(segnums, M_NANDFSTEMP);
@@ -447,7 +464,7 @@ nandfs_cleaner(struct nandfs_device *fsd
int error;
while (!nandfs_cleaner_finished(fsdev)) {
- if (!nandfs_cleaner_enable)
+ if (!nandfs_cleaner_enable || rebooting)
continue;
DPRINTF(CLEAN, ("%s: run started\n", __func__));
@@ -478,7 +495,6 @@ nandfs_cleaner_clean_segments(struct nan
gc = nffsdev->nd_gc_node;
-
DPRINTF(CLEAN, ("%s: enter\n", __func__));
VOP_LOCK(NTOV(gc), LK_EXCLUSIVE);
@@ -504,7 +520,7 @@ nandfs_cleaner_clean_segments(struct nan
/* Delete checkpoints */
for (i = 0; i < npd; i++) {
DPRINTF(CLEAN, ("delete checkpoint: %jx\n",
- (uintmax_t)pd[i].p_start));
+ (uintmax_t)pd[i].p_start));
error = nandfs_delete_cp(nffsdev->nd_cp_node, pd[i].p_start,
pd[i].p_end);
if (error) {
Modified: projects/nand/sys/fs/nandfs/nandfs_cpfile.c
==============================================================================
--- projects/nand/sys/fs/nandfs/nandfs_cpfile.c Wed May 9 14:51:07 2012 (r235181)
+++ projects/nand/sys/fs/nandfs/nandfs_cpfile.c Wed May 9 14:52:03 2012 (r235182)
@@ -256,11 +256,11 @@ nandfs_cp_set_snapshot(struct nandfs_nod
while (prev > cno) {
curr = prev;
nandfs_checkpoint_blk_offset(fsdev, prev, &prev_blk, &offset);
- error = nandfs_bread(cp_node, prev_blk, NOCRED, 0, &bp);
- if (error) {
- brelse(bp);
- return (error);
- }
+ error = nandfs_bread(cp_node, prev_blk, NOCRED, 0, &bp);
+ if (error) {
+ brelse(bp);
+ return (error);
+ }
cnp = (struct nandfs_checkpoint *)(bp->b_data + offset);
list = &cnp->cp_snapshot_list;
prev = list->ssl_prev;
@@ -484,7 +484,7 @@ nandfs_cpinfo_fill(struct nandfs_checkpo
static int
nandfs_get_cpinfo_cp(struct nandfs_node *node, uint64_t cno,
- struct nandfs_cpinfo *nci, uint32_t mnmembs, uint32_t *nmembs)
+ struct nandfs_cpinfo *nci, uint32_t mnmembs, uint32_t *nmembs)
{
struct nandfs_device *fsdev;
struct buf *bp;
@@ -521,7 +521,7 @@ nandfs_get_cpinfo_cp(struct nandfs_node
do {
nandfs_checkpoint_blk_offset(fsdev, cno, &blk, &offset);
remaining = nandfs_checkpoint_blk_remaining(fsdev, cno,
- blk, offset);
+ blk, offset);
error = nandfs_bread(node, blk, NOCRED, 0, &bp);
if (error) {
brelse(bp);
@@ -555,7 +555,7 @@ nandfs_get_cpinfo_cp(struct nandfs_node
static int
nandfs_get_cpinfo_sp(struct nandfs_node *node, uint64_t cno,
- struct nandfs_cpinfo *nci, uint32_t mnmembs, uint32_t *nmembs)
+ struct nandfs_cpinfo *nci, uint32_t mnmembs, uint32_t *nmembs)
{
struct nandfs_checkpoint *cnp;
struct nandfs_cpfile_header *cnh;
@@ -606,7 +606,7 @@ nandfs_get_cpinfo_sp(struct nandfs_node
cnp = (struct nandfs_checkpoint *)(bp->b_data + offset);
flag = cnp->cp_flags;
if (!(flag & NANDFS_CHECKPOINT_SNAPSHOT) ||
- (flag & NANDFS_CHECKPOINT_INVALID))
+ (flag & NANDFS_CHECKPOINT_INVALID))
break;
nci->nci_flags = flag;
Modified: projects/nand/sys/fs/nandfs/nandfs_dat.c
==============================================================================
--- projects/nand/sys/fs/nandfs/nandfs_dat.c Wed May 9 14:51:07 2012 (r235181)
+++ projects/nand/sys/fs/nandfs/nandfs_dat.c Wed May 9 14:52:03 2012 (r235182)
@@ -333,7 +333,7 @@ nandfs_get_dat_bdescs(struct nandfs_devi
(uintmax_t)bd[i].bd_oblocknr, (uintmax_t)bd[i].bd_blocknr,
(uintmax_t)bd[i].bd_offset));
- error = nandfs_bmap_nlookup(dat_node, bd[i].bd_offset, 1, &map);
+ error = nandfs_bmap_lookup(dat_node, bd[i].bd_offset, &map);
if (error)
break;
bd[i].bd_blocknr = map;
Modified: projects/nand/sys/fs/nandfs/nandfs_fs.h
==============================================================================
--- projects/nand/sys/fs/nandfs/nandfs_fs.h Wed May 9 14:51:07 2012 (r235181)
+++ projects/nand/sys/fs/nandfs/nandfs_fs.h Wed May 9 14:52:03 2012 (r235182)
@@ -148,7 +148,7 @@ struct nandfs_fsdata {
uint64_t f_ctime; /* creation time (execution time
of newfs) */
- /* Block size represented as: blocksize = 1 << (f_log_block_size + 10) */
+ /* Block size represented as: blocksize = 1 << (f_log_block_size + 10) */
uint32_t f_log_block_size;
uint16_t f_inode_size; /* size of an inode */
@@ -164,15 +164,13 @@ struct nandfs_fsdata {
uint32_t f_erasesize;
uint64_t f_nsegments; /* number of segm. in filesystem */
- uint64_t f_first_data_block; /* 1st seg disk block number */
+ nandfs_daddr_t f_first_data_block; /* 1st seg disk block number */
uint32_t f_blocks_per_segment; /* number of blocks per segment */
uint32_t f_r_segments_percentage; /* reserved segments percentage */
- uint32_t f_crc_seed; /* seed value of CRC calculation */
-
struct uuid f_uuid; /* 128-bit uuid for volume */
char f_volume_name[16]; /* volume name */
- uint32_t f_pad[103];
+ uint32_t f_pad[104];
} __packed;
#ifdef _KERNEL
@@ -220,7 +218,7 @@ CTASSERT(sizeof(struct nandfs_super_bloc
#define NANDFS_MIN_SEGSIZE NANDFS_DEF_ERASESIZE
-#define NANDFS_CURRENT_REV 8 /* current major revision */
+#define NANDFS_CURRENT_REV 9 /* current major revision */
#define NANDFS_FSDATA_CRC_BYTES offsetof(struct nandfs_fsdata, f_pad)
/* Bytes count of super_block for CRC-calculation */
@@ -297,8 +295,8 @@ CTASSERT(sizeof(struct nandfs_binfo_v) =
/* Convenience union for both types of binfo's */
union nandfs_binfo {
- struct nandfs_binfo_v bi_v;
- struct nandfs_binfo_dat bi_dat;
+ struct nandfs_binfo_v bi_v;
+ struct nandfs_binfo_dat bi_dat;
};
/* Indirect buffers path */
Modified: projects/nand/sys/fs/nandfs/nandfs_segment.c
==============================================================================
--- projects/nand/sys/fs/nandfs/nandfs_segment.c Wed May 9 14:51:07 2012 (r235181)
+++ projects/nand/sys/fs/nandfs/nandfs_segment.c Wed May 9 14:52:03 2012 (r235182)
@@ -42,6 +42,7 @@ __FBSDID("$FreeBSD$");
#include <sys/vnode.h>
#include <sys/buf.h>
#include <sys/bio.h>
+#include <sys/libkern.h>
#include <ddb/ddb.h>
@@ -275,7 +276,7 @@ nandfs_add_superroot(struct nandfs_segin
struct nandfs_super_root *sr;
struct buf *bp = NULL;
uint64_t crc_skip;
- uint32_t crc_seed, crc_calc;
+ uint32_t crc_calc;
int error;
fsdev = seginfo->fsdev;
@@ -300,9 +301,7 @@ nandfs_add_superroot(struct nandfs_segin
sizeof(struct nandfs_inode));
crc_skip = sizeof(sr->sr_sum);
- crc_seed = fsdev->nd_fsdata.f_crc_seed;
- crc_calc = crc32_le(crc_seed, (uint8_t *)sr + crc_skip,
- NANDFS_SR_BYTES - crc_skip);
+ crc_calc = crc32((uint8_t *)sr + crc_skip, NANDFS_SR_BYTES - crc_skip);
sr->sr_sum = crc_calc;
@@ -663,9 +662,9 @@ nandfs_fill_segsum(struct nandfs_segment
struct nandfs_segment_summary *ss;
struct nandfs_device *fsdev;
struct buf *bp;
- uint32_t rest, segsum_size, blocksize;
+ uint32_t rest, segsum_size, blocksize, crc_calc;
uint16_t flags;
- uint8_t *crc_area, crc_skip, crc_seed, crc_calc = 0;
+ uint8_t *crc_area, crc_skip;
DPRINTF(SYNC, ("%s: seg %#jx nblocks %#x sumbytes %#x\n",
__func__, (uintmax_t) seg->seg_num,
@@ -673,7 +672,6 @@ nandfs_fill_segsum(struct nandfs_segment
seg->segsum_bytes));
fsdev = seg->fsdev;
- crc_seed = fsdev->nd_fsdata.f_crc_seed;
flags = NANDFS_SS_LOGBGN | NANDFS_SS_LOGEND;
if (has_sr)
@@ -697,9 +695,9 @@ nandfs_fill_segsum(struct nandfs_segment
segsum_size = seg->segsum_bytes - crc_skip;
rest = min(seg->segsum_bytes, blocksize) - crc_skip;
crc_area = (uint8_t *)ss + crc_skip;
- crc_calc = crc_seed;
+ crc_calc = ~0U;
while (segsum_size > 0) {
- crc_calc = crc32_le(crc_calc, crc_area, rest);
+ crc_calc = crc32_raw(crc_area, rest, crc_calc);
segsum_size -= rest;
if (!segsum_size)
break;
@@ -707,7 +705,7 @@ nandfs_fill_segsum(struct nandfs_segment
crc_area = (uint8_t *)bp->b_data;
rest = segsum_size <= blocksize ? segsum_size : blocksize;
}
- ss->ss_sumsum = crc_calc;
+ ss->ss_sumsum = crc_calc ^ ~0U;
return (ss);
@@ -887,7 +885,7 @@ clean_seginfo(struct nandfs_seginfo *seg
DPRINTF(SYNC, ("%s: seginfo %p\n", __func__, seginfo));
LIST_FOREACH(seg, &seginfo->seg_list, seg_link) {
- nandfs_clean_segblocks(seg, unlock);
+ nandfs_clean_segblocks(seg, unlock);
}
}
@@ -1015,7 +1013,14 @@ nandfs_sync_file(struct vnode *vp)
cp = fsdev->nd_cp_node;
ifile = nmp->nm_ifile_node;
- lockmgr(&fsdev->nd_seg_const, LK_EXCLUSIVE, NULL);
+ NANDFS_WRITEASSERT(fsdev);
+ if (lockmgr(&fsdev->nd_seg_const, LK_UPGRADE, NULL) != 0) {
+ DPRINTF(SYNC, ("%s: lost shared lock\n", __func__));
+ if (lockmgr(&fsdev->nd_seg_const, LK_EXCLUSIVE, NULL) != 0)
+ panic("couldn't lock exclusive");
+ }
+ DPRINTF(SYNC, ("%s: got lock\n", __func__));
+
VOP_LOCK(NTOV(su), LK_EXCLUSIVE);
create_seginfo(fsdev, &seginfo);
@@ -1033,7 +1038,7 @@ nandfs_sync_file(struct vnode *vp)
clean_seginfo(seginfo, 0);
delete_seginfo(seginfo);
VOP_UNLOCK(NTOV(su), 0);
- lockmgr(&fsdev->nd_seg_const, LK_RELEASE, NULL);
+ lockmgr(&fsdev->nd_seg_const, LK_DOWNGRADE, NULL);
nandfs_error("%s: err:%d iterating dirty bufs vp:%p",
__func__, error, vp);
return (error);
@@ -1049,7 +1054,7 @@ nandfs_sync_file(struct vnode *vp)
delete_seginfo(seginfo);
VOP_UNLOCK(NTOV(ifile), 0);
VOP_UNLOCK(NTOV(su), 0);
- lockmgr(&fsdev->nd_seg_const, LK_RELEASE, NULL);
+ lockmgr(&fsdev->nd_seg_const, LK_DOWNGRADE, NULL);
nandfs_error("%s: err:%d updating vp:%p",
__func__, error, vp);
return (error);
@@ -1068,7 +1073,7 @@ nandfs_sync_file(struct vnode *vp)
delete_seginfo(seginfo);
VOP_UNLOCK(NTOV(cp), 0);
VOP_UNLOCK(NTOV(su), 0);
- lockmgr(&fsdev->nd_seg_const, LK_RELEASE, NULL);
+ lockmgr(&fsdev->nd_seg_const, LK_DOWNGRADE, NULL);
nandfs_error("%s: err:%d getting cp:%jx",
__func__, error, fsdev->nd_last_cno + 1);
return (error);
@@ -1085,7 +1090,7 @@ nandfs_sync_file(struct vnode *vp)
delete_seginfo(seginfo);
VOP_UNLOCK(NTOV(cp), 0);
VOP_UNLOCK(NTOV(su), 0);
- lockmgr(&fsdev->nd_seg_const, LK_RELEASE, NULL);
+ lockmgr(&fsdev->nd_seg_const, LK_DOWNGRADE, NULL);
nandfs_error("%s: err:%d setting cp:%jx",
__func__, error, fsdev->nd_last_cno + 1);
return (error);
@@ -1103,7 +1108,7 @@ nandfs_sync_file(struct vnode *vp)
delete_seginfo(seginfo);
VOP_UNLOCK(NTOV(dat), 0);
VOP_UNLOCK(NTOV(su), 0);
- lockmgr(&fsdev->nd_seg_const, LK_RELEASE, NULL);
+ lockmgr(&fsdev->nd_seg_const, LK_DOWNGRADE, NULL);
nandfs_error("%s: err:%d updating seg",
__func__, error);
return (error);
@@ -1114,7 +1119,7 @@ nandfs_sync_file(struct vnode *vp)
VOP_UNLOCK(NTOV(su), 0);
delete_seginfo(seginfo);
- lockmgr(&fsdev->nd_seg_const, LK_RELEASE, NULL);
+ lockmgr(&fsdev->nd_seg_const, LK_DOWNGRADE, NULL);
if (cno_changed && !error) {
if (nandfs_cps_between_sblocks != 0 &&
@@ -1140,6 +1145,7 @@ nandfs_segment_constructor(struct nandfs
fsdev = nmp->nm_nandfsdev;
lockmgr(&fsdev->nd_seg_const, LK_EXCLUSIVE, NULL);
+ DPRINTF(SYNC, ("%s: git lock\n", __func__));
again:
create_seginfo(fsdev, &seginfo);
Modified: projects/nand/sys/fs/nandfs/nandfs_subr.c
==============================================================================
--- projects/nand/sys/fs/nandfs/nandfs_subr.c Wed May 9 14:51:07 2012 (r235181)
+++ projects/nand/sys/fs/nandfs/nandfs_subr.c Wed May 9 14:52:03 2012 (r235182)
@@ -45,6 +45,7 @@ __FBSDID("$FreeBSD$");
#include <sys/malloc.h>
#include <sys/dirent.h>
#include <sys/lockf.h>
+#include <sys/libkern.h>
#include <geom/geom.h>
#include <geom/geom_vfs.h>
@@ -181,27 +182,6 @@ void nandfs_calc_mdt_consts(struct nandf
mdt->groups_per_desc_block * mdt->blocks_per_group + 1;
}
-/* From NetBSD's src/sys/net/if_ethersubr.c */
-uint32_t
-crc32_le(uint32_t crc, const uint8_t *buf, size_t len)
-{
- static const uint32_t crctab[] = {
- 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++) {
- crc ^= buf[i];
- crc = (crc >> 4) ^ crctab[crc & 0xf];
- crc = (crc >> 4) ^ crctab[crc & 0xf];
- }
-
- return (crc);
-}
-
int
nandfs_dev_bread(struct nandfs_device *nandfsdev, nandfs_lbn_t blocknr,
struct ucred *cred, int flags, struct buf **bpp)
@@ -274,12 +254,13 @@ nandfs_bdestroy(struct nandfs_node *node
{
int error;
- NANDFS_WRITEASSERT(node->nn_nandfsdev);
+ if (!NANDFS_SYS_NODE(node->nn_ino))
+ NANDFS_WRITEASSERT(node->nn_nandfsdev);
error = nandfs_vblock_end(node->nn_nandfsdev, vblk);
if (error) {
nandfs_error("%s: ending vblk: %jx failed\n",
- __func__, (uintmax_t)vblk);
+ __func__, (uintmax_t)vblk);
return (error);
}
node->nn_inode.i_blocks--;
@@ -294,7 +275,8 @@ nandfs_bcreate(struct nandfs_node *node,
int error;
ASSERT_VOP_LOCKED(NTOV(node), __func__);
- NANDFS_WRITEASSERT(node->nn_nandfsdev);
+ if (!NANDFS_SYS_NODE(node->nn_ino))
+ NANDFS_WRITEASSERT(node->nn_nandfsdev);
DPRINTF(BLOCK, ("%s: vp:%p lbn:%#jx\n", __func__, NTOV(node),
blocknr));
@@ -311,7 +293,7 @@ nandfs_bcreate(struct nandfs_node *node,
error = nandfs_bmap_insert_block(node, blocknr, *bpp);
if (error) {
nandfs_warning("%s: failed bmap insert node:%p"
- " blk:%jx\n", __func__, node, blocknr);
+ " blk:%jx\n", __func__, node, blocknr);
brelse(*bpp);
return (error);
}
@@ -433,8 +415,8 @@ nandfs_mdt_trans_blk(struct nandfs_mdt *
(uintmax_t)*blocknr, *entry_in_block));
}
-static int
-nandfs_vtop(struct nandfs_device *nandfsdev, nandfs_daddr_t vblocknr,
+int
+nandfs_vtop(struct nandfs_node *node, nandfs_daddr_t vblocknr,
nandfs_daddr_t *pblocknr)
{
struct nandfs_node *dat_node;
@@ -444,8 +426,17 @@ nandfs_vtop(struct nandfs_device *nandfs
uint32_t entry_in_block;
int locked, error;
- dat_node = nandfsdev->nd_dat_node;
- nandfs_mdt_trans(&nandfsdev->nd_dat_mdt, vblocknr, &ldatblknr,
+ if (node->nn_ino == NANDFS_DAT_INO || node->nn_ino == NANDFS_GC_INO) {
+ *pblocknr = vblocknr;
+ return (0);
+ }
+
+ /* only translate valid vblocknrs */
+ if (vblocknr == 0)
+ return (0);
+
+ dat_node = node->nn_nandfsdev->nd_dat_node;
+ nandfs_mdt_trans(&node->nn_nandfsdev->nd_dat_mdt, vblocknr, &ldatblknr,
&entry_in_block);
locked = NANDFS_VOP_ISLOCKED(NTOV(dat_node));
@@ -473,52 +464,12 @@ nandfs_vtop(struct nandfs_device *nandfs
if (!locked)
VOP_UNLOCK(NTOV(dat_node), 0);
- MPASS(*pblocknr >= 0);
+ MPASS(*pblocknr >= node->nn_nandfsdev->nd_fsdata.f_first_data_block ||
+ *pblocknr == 0);
return (0);
}
-
-int
-nandfs_nvtop(struct nandfs_node *node, uint64_t blks, nandfs_daddr_t *l2vmap,
- nandfs_daddr_t *v2pmap)
-{
- nandfs_daddr_t vblocknr;
- uint64_t *pblocknr;
- int i, error;
-
- /* The DAT and GC nodes are the only ones not mapped virtual */
- if (node->nn_ino == NANDFS_DAT_INO || node->nn_ino == NANDFS_GC_INO) {
- memcpy(v2pmap, l2vmap, blks * sizeof(uint64_t));
- return (0);
- }
-
- error = 0;
- for (i = 0; i < blks; i++) {
- vblocknr = l2vmap[i];
- pblocknr = v2pmap + i;
- *pblocknr = 0;
-
- /* only translate valid vblocknrs */
- if (vblocknr == 0)
- continue;
- error = nandfs_vtop(node->nn_nandfsdev, vblocknr, pblocknr);
- if (error)
- break;
- }
-
- return (error);
-}
-
-struct nandfs_recover_info {
- uint64_t segnum;
- uint64_t pseg;
-
- struct nandfs_segment_summary segsum;
- struct nandfs_super_root super_root;
- STAILQ_ENTRY(nandfs_recover_info) next;
-};
-
int
nandfs_segsum_valid(struct nandfs_segment_summary *segsum)
{
@@ -545,47 +496,32 @@ nandfs_load_segsum(struct nandfs_device
if (!nandfs_segsum_valid(segsum)) {
DPRINTF(VOLUMES, ("%s: bad magic pseg:%jx\n", __func__,
- blocknr));
+ blocknr));
return (EINVAL);
}
return (error);
}
-/*
- * Helper functions of nandfs_mount() that actually mounts the media.
- */
-static int
-nandfs_load_segsum_ri(struct nandfs_device *nandfsdev,
- struct nandfs_recover_info *ri)
-{
-
- return (nandfs_load_segsum(nandfsdev, ri->pseg, &ri->segsum));
-}
-
static int
nandfs_load_super_root(struct nandfs_device *nandfsdev,
- struct nandfs_recover_info *ri)
+ struct nandfs_segment_summary *segsum, uint64_t pseg)
{
- struct nandfs_segment_summary *segsum;
struct nandfs_super_root super_root;
struct buf *bp;
uint64_t blocknr;
- uint32_t super_root_crc, comp_crc, crc_seed;
+ uint32_t super_root_crc, comp_crc;
int off, error;
- /* Process segment summary */
- segsum = &ri->segsum;
-
/* Check if there is a superroot */
if ((segsum->ss_flags & NANDFS_SS_SR) == 0) {
DPRINTF(VOLUMES, ("%s: no super root in pseg:%jx\n", __func__,
- ri->pseg));
+ pseg));
return (ENOENT);
}
/* Get our super root, located at the end of the pseg */
- blocknr = ri->pseg + segsum->ss_nblocks - 1;
+ blocknr = pseg + segsum->ss_nblocks - 1;
DPRINTF(VOLUMES, ("%s: try at %#jx\n", __func__, (uintmax_t)blocknr));
error = nandfs_dev_bread(nandfsdev, blocknr, NOCRED, 0, &bp);
@@ -598,8 +534,7 @@ nandfs_load_super_root(struct nandfs_dev
/* Check super root CRC */
super_root_crc = super_root.sr_sum;
off = sizeof(super_root.sr_sum);
- crc_seed = nandfsdev->nd_fsdata.f_crc_seed;
- comp_crc = crc32_le(crc_seed, ((uint8_t *) &super_root) + off,
+ comp_crc = crc32((uint8_t *)&super_root + off,
NANDFS_SR_BYTES - off);
if (super_root_crc != comp_crc) {
@@ -621,96 +556,68 @@ int
nandfs_search_super_root(struct nandfs_device *nandfsdev)
{
struct nandfs_super_block *super;
- struct nandfs_segment_summary *segsum;
- struct nandfs_recover_info *ri, *ori, *i_ri;
*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
More information about the svn-src-projects
mailing list