From owner-svn-src-projects@FreeBSD.ORG Wed May 9 14:52:03 2012 Return-Path: Delivered-To: svn-src-projects@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id D827B106564A; Wed, 9 May 2012 14:52:03 +0000 (UTC) (envelope-from gber@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id BF35E8FC0C; Wed, 9 May 2012 14:52:03 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id q49Eq3NT088547; Wed, 9 May 2012 14:52:03 GMT (envelope-from gber@svn.freebsd.org) Received: (from gber@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id q49Eq31e088531; Wed, 9 May 2012 14:52:03 GMT (envelope-from gber@svn.freebsd.org) Message-Id: <201205091452.q49Eq31e088531@svn.freebsd.org> From: Grzegorz Bernacki Date: Wed, 9 May 2012 14:52:03 +0000 (UTC) To: src-committers@freebsd.org, svn-src-projects@freebsd.org X-SVN-Group: projects MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r235182 - in projects/nand: lib/libnandfs lib/libstand sbin/nandfs sbin/newfs_nandfs sys/fs/nandfs X-BeenThere: svn-src-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the src " projects" tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 09 May 2012 14:52:03 -0000 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 #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 | rmsnap] " + fprintf(stderr, "usage: nandfs [lssnap | mksnap | rmsnap ] " "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 #include #include +#include #include @@ -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 #include #include +#include #include #include @@ -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 ***