From owner-svn-src-projects@FreeBSD.ORG Sat Apr 7 05:17:42 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 675E5106564A; Sat, 7 Apr 2012 05:17:42 +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 508698FC08; Sat, 7 Apr 2012 05:17:42 +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 q375HgmL044156; Sat, 7 Apr 2012 05:17:42 GMT (envelope-from gber@svn.freebsd.org) Received: (from gber@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id q375HgeE044148; Sat, 7 Apr 2012 05:17:42 GMT (envelope-from gber@svn.freebsd.org) Message-Id: <201204070517.q375HgeE044148@svn.freebsd.org> From: Grzegorz Bernacki Date: Sat, 7 Apr 2012 05:17:42 +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: r233981 - projects/nand/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: Sat, 07 Apr 2012 05:17:42 -0000 Author: gber Date: Sat Apr 7 05:17:41 2012 New Revision: 233981 URL: http://svn.freebsd.org/changeset/base/233981 Log: nandfs: Update - add cleaner - minor enhacement - bug fixes Obtained from: Semihalf Supported by: FreeBSD Foundation, Juniper Networks Modified: projects/nand/sys/fs/nandfs/nandfs.h 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/sys/fs/nandfs/nandfs.h ============================================================================== --- projects/nand/sys/fs/nandfs/nandfs.h Sat Apr 7 05:13:02 2012 (r233980) +++ projects/nand/sys/fs/nandfs/nandfs.h Sat Apr 7 05:17:41 2012 (r233981) @@ -122,8 +122,8 @@ struct nandfs_segment { uint64_t start_block; uint32_t num_blocks; - uint32_t nfinfos; uint32_t nblocks; + uint32_t nbinfos; uint32_t segsum_blocks; uint32_t segsum_bytes; uint32_t bytes_left; @@ -135,7 +135,6 @@ struct nandfs_seginfo { struct nandfs_segment *curseg; struct nandfs_device *fsdev; uint32_t blocks; - uint32_t finfos; uint8_t reiterate; }; @@ -146,10 +145,19 @@ struct nandfs_fsarea { int last_used; }; +extern int nandfs_cleaner_enable; +extern int nandfs_cleaner_interval; +extern int nandfs_cleaner_segments; + struct nandfs_device { struct vnode *nd_devvp; struct g_consumer *nd_gconsumer; + struct proc *nd_syncer; + struct proc *nd_cleaner; + int nd_syncer_exit; + int nd_cleaner_exit; + int nd_is_nand; struct nandfs_fsarea nd_fsarea[NANDFS_NFSAREAS]; @@ -177,12 +185,12 @@ struct nandfs_device { struct mtx nd_mutex; struct mtx nd_sync_mtx; struct cv nd_sync_cv; + struct mtx nd_clean_mtx; + struct cv nd_clean_cv; struct lock nd_seg_const; struct nandfs_seginfo *nd_seginfo; - int32_t nd_cleanerd_pid; - /* FS geometry */ uint64_t nd_devsize; uint64_t nd_maxfilesize; @@ -209,14 +217,14 @@ struct nandfs_device { int nd_mount_state; int nd_refcnt; int nd_syncing; + int nd_cleaning; }; extern SLIST_HEAD(_nandfs_devices, nandfs_device) nandfs_devices; #define NANDFS_KILL_SYNCER 0x1 #define NANDFS_FORCE_SYNCER 0x2 -#define NANDFS_NOLOCK_SYNCER 0x4 -#define NANDFS_UMOUNT 0x8 +#define NANDFS_UMOUNT 0x4 #define SYNCER_UMOUNT 0x0 #define SYNCER_VFS_SYNC 0x1 @@ -233,19 +241,11 @@ struct nandfsmount { struct nandfs_device *nm_nandfsdev; struct nandfs_args nm_mount_args; struct nandfs_node *nm_ifile_node; - struct proc *nm_syncer; - struct sysctl_oid *nm_mountpoint_oid; uint8_t nm_flags; int8_t nm_ronly; }; -struct nandfs_indirect{ - TAILQ_ENTRY(nandfs_indirect) list_entry; - struct nandfs_indir indices; - struct buf *bp; -}; - struct nandfs_node { struct vnode *nn_vnode; struct nandfsmount *nn_nmp; Modified: projects/nand/sys/fs/nandfs/nandfs_cpfile.c ============================================================================== --- projects/nand/sys/fs/nandfs/nandfs_cpfile.c Sat Apr 7 05:13:02 2012 (r233980) +++ projects/nand/sys/fs/nandfs/nandfs_cpfile.c Sat Apr 7 05:17:41 2012 (r233981) @@ -137,8 +137,7 @@ nandfs_get_checkpoint(struct nandfs_devi int nandfs_set_checkpoint(struct nandfs_device *fsdev, struct nandfs_node *cp_node, - uint64_t cn, struct nandfs_inode *ifile_inode, uint64_t nblocks, - uint64_t nfinfos) + uint64_t cn, struct nandfs_inode *ifile_inode, uint64_t nblocks) { struct nandfs_cpfile_header *cnh; struct nandfs_checkpoint *cnp; @@ -179,13 +178,12 @@ nandfs_set_checkpoint(struct nandfs_devi cnp->cp_cno = cn; cnp->cp_create = fsdev->nd_ts.tv_sec; cnp->cp_nblk_inc = nblocks; - cnp->cp_inodes_count = nfinfos; cnp->cp_blocks_count = 0; memcpy (&cnp->cp_ifile_inode, ifile_inode, sizeof(cnp->cp_ifile_inode)); - DPRINTF(CPFILE, ("%s: cn:%#jx ctime:%#jx nblk:%#jx nino:%#jx\n", + DPRINTF(CPFILE, ("%s: cn:%#jx ctime:%#jx nblk:%#jx\n", __func__, (uintmax_t)cn, (uintmax_t)cnp->cp_create, - (uintmax_t)nblocks, (uintmax_t)nfinfos)); + (uintmax_t)nblocks)); brelse(bp); return (0); @@ -477,7 +475,6 @@ nandfs_cpinfo_fill(struct nandfs_checkpo nci->nci_cno = cnp->cp_cno; nci->nci_create = cnp->cp_create; nci->nci_nblk_inc = cnp->cp_nblk_inc; - nci->nci_inodes_count = cnp->cp_inodes_count; nci->nci_blocks_count = cnp->cp_blocks_count; nci->nci_next = cnp->cp_snapshot_list.ssl_next; DPRINTF(CPFILE, ("%s: cn:%#jx ctime:%#jx\n", @@ -575,7 +572,8 @@ nandfs_get_cpinfo_sp(struct nandfs_node fsdev = node->nn_nandfsdev; curr_cno = cno; - *nmembs = 0; + if (nmembs) + *nmembs = 0; if (curr_cno == 1) { /* Get list from header */ error = nandfs_bread(node, 0, NOCRED, 0, &bp); @@ -616,10 +614,10 @@ nandfs_get_cpinfo_sp(struct nandfs_node nci->nci_cno = cnp->cp_cno; nci->nci_create = cnp->cp_create; nci->nci_nblk_inc = cnp->cp_nblk_inc; - nci->nci_inodes_count = cnp->cp_inodes_count; nci->nci_blocks_count = cnp->cp_blocks_count; nci->nci_next = cnp->cp_snapshot_list.ssl_next; - (*nmembs)++; + if (nmembs) + (*nmembs)++; curr_cno = nci->nci_next; if (!curr_cno) @@ -632,30 +630,18 @@ nandfs_get_cpinfo_sp(struct nandfs_node } int -nandfs_get_cpinfo(struct nandfs_node *node, struct nandfs_argv *nargv) +nandfs_get_cpinfo(struct nandfs_node *node, uint64_t cno, uint16_t flags, + struct nandfs_cpinfo *nci, uint32_t nmembs, uint32_t *nnmembs) { - struct nandfs_cpinfo *nci; - uint64_t cno = nargv->nv_index; - void *buf = (void *)((uintptr_t)nargv->nv_base); - uint16_t flags = nargv->nv_flags; - uint32_t nmembs = 0; int error; - if (nargv->nv_nmembs > NANDFS_CPINFO_MAX) - return (EINVAL); - - nci = malloc(sizeof(struct nandfs_cpinfo) * nargv->nv_nmembs, - M_NANDFSTEMP, M_WAITOK | M_ZERO); - VOP_LOCK(NTOV(node), LK_EXCLUSIVE); switch (flags) { case NANDFS_CHECKPOINT: - error = nandfs_get_cpinfo_cp(node, cno, nci, nargv->nv_nmembs, - &nmembs); + error = nandfs_get_cpinfo_cp(node, cno, nci, nmembs, nnmembs); break; case NANDFS_SNAPSHOT: - error = nandfs_get_cpinfo_sp(node, cno, nci, nargv->nv_nmembs, - &nmembs); + error = nandfs_get_cpinfo_sp(node, cno, nci, nmembs, nnmembs); break; default: error = EINVAL; @@ -663,6 +649,27 @@ nandfs_get_cpinfo(struct nandfs_node *no } VOP_UNLOCK(NTOV(node), 0); + return (error); +} + +int +nandfs_get_cpinfo_ioctl(struct nandfs_node *node, struct nandfs_argv *nargv) +{ + struct nandfs_cpinfo *nci; + uint64_t cno = nargv->nv_index; + void *buf = (void *)((uintptr_t)nargv->nv_base); + uint16_t flags = nargv->nv_flags; + uint32_t nmembs = 0; + int error; + + if (nargv->nv_nmembs > NANDFS_CPINFO_MAX) + return (EINVAL); + + nci = malloc(sizeof(struct nandfs_cpinfo) * nargv->nv_nmembs, + M_NANDFSTEMP, M_WAITOK | M_ZERO); + + error = nandfs_get_cpinfo(node, cno, flags, nci, nargv->nv_nmembs, &nmembs); + if (error == 0) { nargv->nv_nmembs = nmembs; error = copyout(nci, buf, Modified: projects/nand/sys/fs/nandfs/nandfs_dat.c ============================================================================== --- projects/nand/sys/fs/nandfs/nandfs_dat.c Sat Apr 7 05:13:02 2012 (r233980) +++ projects/nand/sys/fs/nandfs/nandfs_dat.c Sat Apr 7 05:17:41 2012 (r233981) @@ -222,26 +222,16 @@ nandfs_vblock_free(struct nandfs_device } int -nandfs_get_dat_vinfo(struct nandfs_device *nandfsdev, struct nandfs_argv *nargv) +nandfs_get_dat_vinfo_ioctl(struct nandfs_device *nandfsdev, struct nandfs_argv *nargv) { - struct nandfs_node *dat; - struct nandfs_mdt *mdt; - struct nandfs_alloc_request req; - struct nandfs_dat_entry *dat_entry; struct nandfs_vinfo *vinfo; size_t size; - uint32_t i, nmembs, idx; int error; - dat = nandfsdev->nd_dat_node; - mdt = &nandfsdev->nd_dat_mdt; - - nmembs = nargv->nv_nmembs; - - if (nmembs > NANDFS_VINFO_MAX) + if (nargv->nv_nmembs > NANDFS_VINFO_MAX) return (EINVAL); - size = sizeof(struct nandfs_vinfo) * nmembs; + size = sizeof(struct nandfs_vinfo) * nargv->nv_nmembs; vinfo = malloc(size, M_NANDFSTEMP, M_WAITOK|M_ZERO); error = copyin((void *)(uintptr_t)nargv->nv_base, vinfo, size); @@ -250,6 +240,27 @@ nandfs_get_dat_vinfo(struct nandfs_devic return (error); } + error = nandfs_get_dat_vinfo(nandfsdev, vinfo, nargv->nv_nmembs); + if (error == 0) + error = copyout(vinfo, (void *)(uintptr_t)nargv->nv_base, size); + free(vinfo, M_NANDFSTEMP); + return (error); +} + +int +nandfs_get_dat_vinfo(struct nandfs_device *nandfsdev, struct nandfs_vinfo *vinfo, + uint32_t nmembs) +{ + struct nandfs_node *dat; + struct nandfs_mdt *mdt; + struct nandfs_alloc_request req; + struct nandfs_dat_entry *dat_entry; + uint32_t i, idx; + int error = 0; + + dat = nandfsdev->nd_dat_node; + mdt = &nandfsdev->nd_dat_mdt; + DPRINTF(DAT, ("%s: nmembs %#x\n", __func__, nmembs)); VOP_LOCK(NTOV(dat), LK_EXCLUSIVE); @@ -274,9 +285,60 @@ nandfs_get_dat_vinfo(struct nandfs_devic } VOP_UNLOCK(NTOV(dat), 0); + return (error); +} + +int +nandfs_get_dat_bdescs_ioctl(struct nandfs_device *nffsdev, + struct nandfs_argv *nargv) +{ + struct nandfs_bdesc *bd; + size_t size; + int error; + + size = nargv->nv_nmembs * sizeof(struct nandfs_bdesc); + bd = malloc(size, M_NANDFSTEMP, M_WAITOK); + error = copyin((void *)(uintptr_t)nargv->nv_base, bd, size); + if (error) { + free(bd, M_NANDFSTEMP); + return (error); + } + + error = nandfs_get_dat_bdescs(nffsdev, bd, nargv->nv_nmembs); if (error == 0) - error = copyout(vinfo, (void *)(uintptr_t)nargv->nv_base, size); - free(vinfo, M_NANDFSTEMP); + error = copyout(bd, (void *)(uintptr_t)nargv->nv_base, size); + + free(bd, M_NANDFSTEMP); + return (error); +} + +int +nandfs_get_dat_bdescs(struct nandfs_device *nffsdev, struct nandfs_bdesc *bd, + uint32_t nmembs) +{ + struct nandfs_node *dat_node; + uint64_t map; + uint32_t i; + int error = 0; + + dat_node = nffsdev->nd_dat_node; + + VOP_LOCK(NTOV(dat_node), LK_EXCLUSIVE); + + for (i = 0; i < nmembs; i++) { + DPRINTF(CLEAN, + ("%s: bd ino:%#jx oblk:%#jx blocknr:%#jx off:%#jx\n", + __func__, (uintmax_t)bd[i].bd_ino, + (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); + if (error) + break; + bd[i].bd_blocknr = map; + } + + VOP_UNLOCK(NTOV(dat_node), 0); return (error); } Modified: projects/nand/sys/fs/nandfs/nandfs_fs.h ============================================================================== --- projects/nand/sys/fs/nandfs/nandfs_fs.h Sat Apr 7 05:13:02 2012 (r233980) +++ projects/nand/sys/fs/nandfs/nandfs_fs.h Sat Apr 7 05:17:41 2012 (r233981) @@ -33,6 +33,8 @@ #ifndef _NANDFS_FS_H #define _NANDFS_FS_H +#include + #define MNINDIR(fsdev) ((fsdev)->nd_blocksize / sizeof(nandfs_daddr_t)) /* @@ -175,7 +177,7 @@ struct nandfs_fsdata { uint32_t f_crc_seed; /* seed value of CRC calculation */ - uint8_t f_uuid[16]; /* 128-bit uuid for volume */ + struct uuid f_uuid; /* 128-bit uuid for volume */ char f_volume_name[16]; /* volume name */ uint32_t f_pad[96]; } __packed; @@ -276,35 +278,34 @@ struct nandfs_dir_entry { * files and optionally a super root. */ -struct nandfs_finfo { - uint64_t fi_ino; /* inode number */ - uint64_t fi_cno; /* checkpoint associated with this */ - uint32_t fi_nblocks; /* size in blocks of this finfo */ - uint32_t fi_ndatablk; /* number of data blocks */ -}; - /* * Virtual to physical block translation information. For data blocks it maps * logical block number bi_blkoff to virtual block nr bi_vblocknr. For non * datablocks it is the virtual block number assigned to an indirect block * and has no bi_blkoff. The physical block number is the next - * available data block in the partial segment after all the finfo's. + * available data block in the partial segment after all the binfo's. */ struct nandfs_binfo_v { + uint64_t bi_ino; /* file's inode */ uint64_t bi_vblocknr; /* assigned virtual block number */ uint64_t bi_blkoff; /* for file's logical block number */ }; /* * DAT allocation. For data blocks just the logical block number that maps on - * the next available data block in the partial segment after the finfo's. + * the next available data block in the partial segment after the binfo's. */ struct nandfs_binfo_dat { + uint64_t bi_ino; uint64_t bi_blkoff; /* DAT file's logical block number */ uint8_t bi_level; /* whether this is meta block */ uint8_t bi_pad[7]; }; +#ifdef _KERNEL +CTASSERT(sizeof(struct nandfs_binfo_v) == sizeof(struct nandfs_binfo_dat)); +#endif + /* Convenience union for both types of binfo's */ union nandfs_binfo { struct nandfs_binfo_v bi_v; @@ -327,11 +328,11 @@ struct nandfs_segment_summary { uint64_t ss_seq; /* sequence number of this segm. sum */ uint64_t ss_create; /* creation timestamp in seconds */ uint64_t ss_next; /* blocknumber of next segment */ - uint32_t ss_nblocks; /* number of blocks follow */ - uint32_t ss_nfinfo; /* number of finfo structures follow */ + uint32_t ss_nblocks; /* number of blocks used by summary */ + uint32_t ss_nbinfos; /* number of binfo structures */ uint32_t ss_sumbytes; /* total size of segment summary */ uint32_t ss_pad; - /* stream of finfo structures */ + /* stream of binfo structures */ }; #define NANDFS_SEGSUM_MAGIC 0x8e680011 /* segment summary magic number */ @@ -382,7 +383,7 @@ struct nandfs_dat_entry { * Structure of CP file. * * A snapshot is just a checkpoint only it's protected against removal by the - * cleanerd. The snapshots are kept on a double linked list of checkpoints. + * cleaner. The snapshots are kept on a double linked list of checkpoints. */ struct nandfs_snapshot_list { uint64_t ssl_next; /* checkpoint nr. forward */ @@ -397,7 +398,6 @@ struct nandfs_checkpoint { uint64_t cp_cno; /* checkpoint number */ uint64_t cp_create; /* creation timestamp */ uint64_t cp_nblk_inc; /* number of blocks incremented */ - uint64_t cp_inodes_count; /* number of inodes in this cp. */ uint64_t cp_blocks_count; /* reserved (might be deleted) */ struct nandfs_inode cp_ifile_inode; /* inode file inode */ }; @@ -421,6 +421,9 @@ struct nandfs_cpfile_header { sizeof(struct nandfs_checkpoint) - 1) / \ sizeof(struct nandfs_checkpoint)) + +#define NANDFS_NOSEGMENT 0xffffffff + /* * Structure of SU file. * @@ -475,7 +478,6 @@ struct nandfs_cpinfo { uint64_t nci_cno; uint64_t nci_create; uint64_t nci_nblk_inc; - uint64_t nci_inodes_count; uint64_t nci_blocks_count; uint64_t nci_next; }; @@ -483,6 +485,7 @@ struct nandfs_cpinfo { #define NANDFS_SEGMENTS_MAX 512 struct nandfs_suinfo { + uint64_t nsi_num; uint64_t nsi_lastmod; uint32_t nsi_blocks; uint32_t nsi_flags; @@ -491,10 +494,12 @@ struct nandfs_suinfo { #define NANDFS_VINFO_MAX 512 struct nandfs_vinfo { + uint64_t nvi_ino; uint64_t nvi_vblocknr; uint64_t nvi_start; uint64_t nvi_end; uint64_t nvi_blocknr; + int nvi_alive; }; struct nandfs_cpmode { @@ -506,6 +511,7 @@ struct nandfs_cpmode { struct nandfs_argv { uint64_t nv_base; uint32_t nv_nmembs; + uint16_t nv_size; uint16_t nv_flags; uint64_t nv_index; }; @@ -538,7 +544,7 @@ struct nandfs_bdesc { uint64_t bd_blocknr; uint64_t bd_offset; uint32_t bd_level; - uint32_t bd_pad; + uint32_t bd_alive; }; #ifndef _KERNEL @@ -559,16 +565,13 @@ struct nandfs_fsinfo { #define NANDFS_IOCTL_CHANGE_CPMODE _IOWR('N', 101, struct nandfs_cpmode) #define NANDFS_IOCTL_GET_CPINFO _IOWR('N', 102, struct nandfs_argv) #define NANDFS_IOCTL_DELETE_CP _IOWR('N', 103, uint64_t[2]) -#define NANDFS_IOCTL_CPSTAT _IOR('N', 104, struct nandfs_cpstat) +#define NANDFS_IOCTL_GET_CPSTAT _IOR('N', 104, struct nandfs_cpstat) #define NANDFS_IOCTL_GET_SUINFO _IOWR('N', 105, struct nandfs_argv) #define NANDFS_IOCTL_GET_VINFO _IOWR('N', 106, struct nandfs_argv) #define NANDFS_IOCTL_GET_BDESCS _IOWR('N', 107, struct nandfs_argv) -#define NANDFS_IOCTL_CLEAN_SEGMENTS _IOWR('N', 108, struct nandfs_argv[5]) -#define NANDFS_IOCTL_SYNC _IOWR('N', 109, uint64_t) -#define NANDFS_IOCTL_GET_FSINFO _IOR('N', 110, struct nandfs_fsinfo) -#define NANDFS_IOCTL_CLEANERD_SET _IO('N', 111) -#define NANDFS_IOCTL_CLEANERD_UNSET _IO('N', 112) -#define NANDFS_IOCTL_MAKE_SNAP _IOWR('N', 113, uint64_t) -#define NANDFS_IOCTL_DELETE_SNAP _IOWR('N', 114, uint64_t) +#define NANDFS_IOCTL_GET_FSINFO _IOR('N', 108, struct nandfs_fsinfo) +#define NANDFS_IOCTL_MAKE_SNAP _IOWR('N', 109, uint64_t) +#define NANDFS_IOCTL_DELETE_SNAP _IOWR('N', 110, uint64_t) +#define NANDFS_IOCTL_SYNC _IOWR('N', 111, uint64_t) #endif /* _NANDFS_FS_H */ Modified: projects/nand/sys/fs/nandfs/nandfs_segment.c ============================================================================== --- projects/nand/sys/fs/nandfs/nandfs_segment.c Sat Apr 7 05:13:02 2012 (r233980) +++ projects/nand/sys/fs/nandfs/nandfs_segment.c Sat Apr 7 05:17:41 2012 (r233981) @@ -109,6 +109,11 @@ create_segment(struct nandfs_seginfo *se return (error); } start_block = fsdev->nd_last_pseg + (uint64_t)nblocks; + /* + * XXX hack + */ + if (blks_per_seg - (start_block % blks_per_seg) - 1 == 0) + start_block++; curr = nandfs_get_segnum_of_block(fsdev, start_block); /* Allocate new segment if last one is full */ if (fsdev->nd_seg_num != curr) { @@ -150,7 +155,8 @@ create_segment(struct nandfs_seginfo *se seg->segsum_bytes = sizeof(struct nandfs_segment_summary); /* Allocate buffer for segment summary */ - bp = nandfs_geteblk(fsdev->nd_blocksize, 0); + bp = getblk(fsdev->nd_devvp, nandfs_block_to_dblock(fsdev, + seg->start_block), fsdev->nd_blocksize, 0, 0, 0); bzero(bp->b_data, seginfo->fsdev->nd_blocksize); bp->b_bufobj = &seginfo->fsdev->nd_devvp->v_bufobj; bp->b_flags |= B_MANAGED; @@ -207,7 +213,6 @@ create_seginfo(struct nandfs_device *fsd info->fsdev = fsdev; info->curseg = NULL; info->blocks = 0; - info->finfos = 0; *seginfo = info; fsdev->nd_seginfo = info; return (0); @@ -308,14 +313,13 @@ nandfs_add_superroot(struct nandfs_segin } static int -nandfs_add_segsum_block(struct nandfs_seginfo *seginfo, struct buf **newbp, - int *new_seg) +nandfs_add_segsum_block(struct nandfs_seginfo *seginfo, struct buf **newbp) { + struct nandfs_device *fsdev; + nandfs_daddr_t blk; struct buf *bp; int error; - *new_seg = 0; - if (!(seginfo->curseg) || seginfo->curseg->num_blocks <= 1) { error = create_segment(seginfo); if (error) { @@ -324,11 +328,14 @@ nandfs_add_segsum_block(struct nandfs_se return (error); } *newbp = TAILQ_FIRST(&seginfo->curseg->segsum); - *new_seg = 1; return (0); } - bp = nandfs_geteblk(seginfo->fsdev->nd_blocksize, GB_NOWAIT_BD); + fsdev = seginfo->fsdev; + blk = nandfs_block_to_dblock(fsdev, seginfo->curseg->start_block + + seginfo->curseg->segsum_blocks); + + bp = getblk(fsdev->nd_devvp, blk, fsdev->nd_blocksize, 0, 0, 0); bzero(bp->b_data, seginfo->fsdev->nd_blocksize); bp->b_bufobj = &seginfo->fsdev->nd_devvp->v_bufobj; @@ -336,8 +343,8 @@ nandfs_add_segsum_block(struct nandfs_se TAILQ_INSERT_TAIL(&seginfo->curseg->segsum, bp, b_cluster.cluster_entry); - seginfo->curseg->num_blocks--; + seginfo->curseg->segsum_blocks++; seginfo->curseg->bytes_left = seginfo->fsdev->nd_blocksize; seginfo->curseg->current_off = bp->b_data; @@ -351,48 +358,12 @@ nandfs_add_segsum_block(struct nandfs_se } static int -nandfs_fill_finfo(struct nandfs_seginfo *seginfo, struct nandfs_node *node) -{ - struct nandfs_finfo *finfo; - struct buf *bp; - int new_seg, error; - - if (!(seginfo->curseg) || - seginfo->curseg->bytes_left < sizeof(struct nandfs_finfo)) { - error = nandfs_add_segsum_block(seginfo, &bp, &new_seg); - if (error) { - nandfs_error("%s: cannot add new block for segsum" - " for seg:%p node:%p\n", __func__, seginfo, node); - return (error); - } - } - - seginfo->curseg->nfinfos++; - seginfo->finfos++; - - finfo = (struct nandfs_finfo *)seginfo->curseg->current_off; - finfo->fi_ino = node->nn_ino; - finfo->fi_ndatablk = 0; - finfo->fi_nblocks = 0; - finfo->fi_cno = seginfo->fsdev->nd_last_cno + 1; - DPRINTF(SYNC, ("%s: finfo %p ino %#jx cno %#jx\n", __func__, - finfo, node->nn_ino, (uintmax_t)seginfo->fsdev->nd_last_cno + 1)); - - finfo++; - seginfo->curseg->bytes_left -= sizeof(struct nandfs_finfo); - seginfo->curseg->segsum_bytes += sizeof(struct nandfs_finfo); - seginfo->curseg->current_off = (char *)finfo; - - return (0); -} - -static int nandfs_add_blocks(struct nandfs_seginfo *seginfo, struct nandfs_node *node, struct buf *bp) { union nandfs_binfo *binfo; struct buf *seg_bp; - int new_seg, error; + int error; if (!(seginfo->curseg) || !seginfo->curseg->num_blocks) { error = create_segment(seginfo); @@ -401,26 +372,24 @@ nandfs_add_blocks(struct nandfs_seginfo __func__, error); return (error); } - nandfs_fill_finfo(seginfo, node); } - binfo = (union nandfs_binfo *)seginfo->curseg->current_off; if (seginfo->curseg->bytes_left < sizeof(union nandfs_binfo)) { - error = nandfs_add_segsum_block(seginfo, &seg_bp, &new_seg); + error = nandfs_add_segsum_block(seginfo, &seg_bp); if (error) { nandfs_error("%s: error:%d when adding segsum\n", __func__, error); return (error); } - if (new_seg == 1) - nandfs_fill_finfo(seginfo, node); - binfo = (union nandfs_binfo *)seginfo->curseg->current_off; } + binfo = (union nandfs_binfo *)seginfo->curseg->current_off; - if (node->nn_ino != NANDFS_DAT_INO) + if (node->nn_ino != NANDFS_DAT_INO) { binfo->bi_v.bi_blkoff = bp->b_lblkno; - else { + binfo->bi_v.bi_ino = node->nn_ino; + } else { binfo->bi_dat.bi_blkoff = bp->b_lblkno; + binfo->bi_dat.bi_ino = node->nn_ino; if (NANDFS_IS_INDIRECT(bp)) binfo->bi_dat.bi_level = 1; else @@ -434,6 +403,7 @@ nandfs_add_blocks(struct nandfs_seginfo TAILQ_INSERT_TAIL(&seginfo->curseg->data, bp, b_cluster.cluster_entry); + seginfo->curseg->nbinfos++; seginfo->curseg->nblocks++; seginfo->curseg->num_blocks--; seginfo->blocks++; @@ -451,7 +421,6 @@ nandfs_iterate_dirty_buf(struct vnode *v struct buf *bp, *tbd; struct bufobj *bo; struct nandfs_node *node; - int finfo = 0; int error; node = VTON(vp); @@ -465,9 +434,6 @@ nandfs_iterate_dirty_buf(struct vnode *v "add buf\n", __func__, vp, bp, bp->b_lblkno, node->nn_ino)); if (!(NANDFS_ISGATHERED(bp))) { - if (!finfo) - nandfs_fill_finfo(seginfo, node); - finfo = 1; error = nandfs_bmap_update_dat(node, nandfs_vblk_get(bp), bp); if (error) @@ -590,6 +556,7 @@ nandfs_update_phys_block(struct nandfs_d nandfs_vblock_assign(fsdev, new_blknr, phys_blknr); binfo->bi_v.bi_vblocknr = new_blknr; binfo->bi_v.bi_blkoff = bp->b_lblkno; + binfo->bi_v.bi_ino = node->nn_ino; } else { VOP_LOCK(NTOV(dat), LK_EXCLUSIVE); error = nandfs_bmap_update_block(node, bp, phys_blknr); @@ -601,6 +568,7 @@ nandfs_update_phys_block(struct nandfs_d } VOP_UNLOCK(NTOV(dat), 0); binfo->bi_dat.bi_blkoff = bp->b_lblkno; + binfo->bi_dat.bi_ino = node->nn_ino; if (NANDFS_IS_INDIRECT(bp)) binfo->bi_dat.bi_level = 1; else @@ -610,23 +578,19 @@ nandfs_update_phys_block(struct nandfs_d return (0); } -#define NFINFO(off) ((off) + sizeof(struct nandfs_finfo)) #define NBINFO(off) ((off) + sizeof(union nandfs_binfo)) static int nandfs_segment_assign_pblk(struct nandfs_segment *nfsseg) { struct nandfs_device *fsdev; - struct nandfs_finfo *finfo; union nandfs_binfo *binfo; struct buf *bp, *seg_bp; - uint64_t blocknr, dblocks, ablocks, ino; + uint64_t blocknr; uint32_t curr_off, blocksize; - int nfinfo = 0, error; + int error; fsdev = nfsseg->fsdev; blocksize = fsdev->nd_blocksize; - finfo = NULL; - dblocks = ablocks = ino = 0; blocknr = nfsseg->start_block + nfsseg->segsum_blocks; seg_bp = TAILQ_FIRST(&nfsseg->segsum); @@ -639,44 +603,10 @@ nandfs_segment_assign_pblk(struct nandfs TAILQ_FOREACH(bp, &nfsseg->data, b_cluster.cluster_entry) { KASSERT((bp->b_vp), ("bp %p has not vp", bp)); - if ((VTON(bp->b_vp)->nn_ino) != ino) { - /* If not the first one, update block counts */ - if (finfo) { - finfo->fi_nblocks = ablocks; - finfo->fi_ndatablk = dblocks; - DPRINTF(SYNC, - ("%s: update finfo %p ino %#jx nblk %#x " - "dblk %#x\n", __func__, - finfo, finfo->fi_ino, finfo->fi_nblocks, - finfo->fi_ndatablk)); - } - - finfo = (struct nandfs_finfo *)binfo; - nfinfo++; - - if (NFINFO(curr_off) > blocksize) { - seg_bp = TAILQ_NEXT(seg_bp, - b_cluster.cluster_entry); - finfo = (struct nandfs_finfo *)seg_bp->b_data; - curr_off = 0; - DPRINTF(SYNC, - ("%s: next segsum %p data %p\n", - __func__, seg_bp, seg_bp->b_data)); - } - - ino = VTON(bp->b_vp)->nn_ino; - KASSERT((VTON(bp->b_vp)->nn_ino == finfo->fi_ino), - ("bp <=> finfo ino mismatch bp:%p finfo:%p", bp, - finfo)); - - dblocks = ablocks = 0; - curr_off += sizeof(struct nandfs_finfo); - binfo = (union nandfs_binfo *)(finfo + 1); - } DPRINTF(BMAP, ("\n\n%s: assign buf %p for ino %#jx next %p\n", - __func__, bp, (uintmax_t)VTON(bp->b_vp)->nn_ino, - TAILQ_NEXT(bp, b_cluster.cluster_entry))); + __func__, bp, (uintmax_t)VTON(bp->b_vp)->nn_ino, + TAILQ_NEXT(bp, b_cluster.cluster_entry))); if (NBINFO(curr_off) > blocksize) { seg_bp = TAILQ_NEXT(seg_bp, b_cluster.cluster_entry); @@ -697,38 +627,6 @@ nandfs_segment_assign_pblk(struct nandfs curr_off = NBINFO(curr_off); blocknr++; - ablocks++; - if (!NANDFS_IS_INDIRECT(bp)) - dblocks++; - } - - /* If there is one block rest of segment */ - if (finfo == NULL) { - finfo = (struct nandfs_finfo *)binfo; - if (finfo == NULL) { - nandfs_error("%s: finfo is NULL\n", __func__); - return (-1); - } - nfinfo++; - } - - finfo->fi_nblocks = ablocks; - finfo->fi_ndatablk = dblocks; - DPRINTF(SYNC, ("%s:update finfo %p ino %#jx nblk %#x dblk %#x\n", - __func__, finfo, finfo->fi_ino, finfo->fi_nblocks, - finfo->fi_ndatablk)); - - if (nfsseg->nfinfos != nfinfo) { - nfsseg->nfinfos = nfinfo; - finfo = (struct nandfs_finfo *)binfo; - if (NFINFO(curr_off) > blocksize) { - seg_bp = TAILQ_NEXT(seg_bp, b_cluster.cluster_entry); - finfo = (struct nandfs_finfo *)seg_bp->b_data; - DPRINTF(SYNC, - ("%s: next segsum %p data %p\n", - __func__, seg_bp, seg_bp->b_data)); - } - bzero(finfo, sizeof(*finfo)); } return (0); @@ -759,10 +657,10 @@ nandfs_fill_segsum(struct nandfs_segment uint16_t flags; uint8_t *crc_area, crc_skip, crc_seed, crc_calc = 0; - DPRINTF(SYNC, ("%s: seg %#jx nblocks %#x nfinfo %#x sumbytes %#x\n", + DPRINTF(SYNC, ("%s: seg %#jx nblocks %#x sumbytes %#x\n", __func__, (uintmax_t) seg->seg_num, seg->nblocks + seg->segsum_blocks, - seg->nfinfos, seg->segsum_bytes)); + seg->segsum_bytes)); fsdev = seg->fsdev; crc_seed = fsdev->nd_fsdata.f_crc_seed; @@ -780,7 +678,7 @@ nandfs_fill_segsum(struct nandfs_segment ss->ss_create = fsdev->nd_ts.tv_sec; nandfs_get_segment_range(fsdev, seg->seg_next, &ss->ss_next, NULL); ss->ss_nblocks = seg->nblocks + seg->segsum_blocks; - ss->ss_nfinfo = seg->nfinfos; + ss->ss_nbinfos = seg->nbinfos; ss->ss_sumbytes = seg->segsum_bytes; crc_skip = sizeof(ss->ss_datasum) + sizeof(ss->ss_sumsum); @@ -809,15 +707,11 @@ static int nandfs_save_buf(struct buf *bp, uint64_t blocknr, struct nandfs_device *fsdev) { struct bufobj *bo; - uint32_t blocksize; - off_t offset; int error; bo = &fsdev->nd_devvp->v_bufobj; - blocksize = fsdev->nd_blocksize; - offset = blocknr * blocksize; - bp->b_blkno = btodb(offset); + bp->b_blkno = nandfs_block_to_dblock(fsdev, blocknr); bp->b_iooffset = dbtob(bp->b_blkno); KASSERT(bp->b_bufobj != NULL, ("no bufobj for %p", bp)); @@ -830,7 +724,7 @@ nandfs_save_buf(struct buf *bp, uint64_t DPRINTF(SYNC, ("%s: buf: %p offset %#jx blk %#jx size %#x\n", __func__, bp, (uintmax_t)bp->b_offset, (uintmax_t)blocknr, - blocksize)); + fsdev->nd_blocksize)); NANDFS_UNGATHER(bp); nandfs_buf_clear(bp, 0xffffffff); @@ -1027,7 +921,7 @@ out: return (error); } -/* Process segments marks to free by cleanerd */ +/* Process segments marks to free by cleaner */ static void nandfs_process_segments(struct nandfs_device *fsdev) { @@ -1038,6 +932,8 @@ nandfs_process_segments(struct nandfs_de saved_segment = nandfs_get_segnum_of_block(fsdev, fsdev->nd_super.s_last_pseg); for (i = 0; i < fsdev->nd_free_count; i++) { + if (fsdev->nd_free_base[i] == NANDFS_NOSEGMENT) + continue; /* Update superblock if clearing segment point by it */ if (fsdev->nd_free_base[i] == saved_segment) { nandfs_write_superblock(fsdev); @@ -1142,7 +1038,7 @@ nandfs_sync_file(struct vnode *vp) /* Fill checkpoint data */ error = nandfs_set_checkpoint(fsdev, cp, fsdev->nd_last_cno + 1, - &ifile->nn_inode, seginfo->blocks, seginfo->finfos); + &ifile->nn_inode, seginfo->blocks); if (error) { clean_seginfo(seginfo, 0); delete_seginfo(seginfo); @@ -1270,7 +1166,7 @@ reiterate: /* Fill checkpoint data */ nandfs_set_checkpoint(fsdev, cp, fsdev->nd_last_cno + 1, - &ifile->nn_inode, seginfo->blocks, seginfo->finfos); + &ifile->nn_inode, seginfo->blocks); LIST_FOREACH(seg, &seginfo->seg_list, seg_link) nandfs_update_segment(fsdev, seg->seg_num, Modified: projects/nand/sys/fs/nandfs/nandfs_subr.c ============================================================================== --- projects/nand/sys/fs/nandfs/nandfs_subr.c Sat Apr 7 05:13:02 2012 (r233980) +++ projects/nand/sys/fs/nandfs/nandfs_subr.c Sat Apr 7 05:17:41 2012 (r233981) @@ -512,39 +512,43 @@ struct nandfs_recover_info { STAILQ_ENTRY(nandfs_recover_info) next; }; -/* - * Helper functions of nandfs_mount() that actually mounts the media. - */ -static int -nandfs_load_segsum(struct nandfs_device *nandfsdev, - struct nandfs_recover_info *ri) +int +nandfs_load_segsum(struct nandfs_device *fsdev, nandfs_daddr_t blocknr, + struct nandfs_segment_summary *segsum) { struct buf *bp; - uint64_t blocknr; int error; - /* Read in segsum structure */ - blocknr = ri->pseg; DPRINTF(VOLUMES, ("nandfs: try segsum at block %jx\n", (uintmax_t)blocknr)); - /* Read in block */ - error = nandfs_dev_bread(nandfsdev, blocknr, NOCRED, 0, &bp); + error = nandfs_dev_bread(fsdev, blocknr, NOCRED, 0, &bp); if (error) return (error); - memcpy(&ri->segsum, bp->b_data, sizeof(struct nandfs_segment_summary)); + memcpy(segsum, bp->b_data, sizeof(struct nandfs_segment_summary)); brelse(bp); - if (ri->segsum.ss_magic != NANDFS_SEGSUM_MAGIC) { + if (segsum->ss_magic != NANDFS_SEGSUM_MAGIC) { DPRINTF(VOLUMES, ("%s: bad magic pseg:%jx\n", __func__, - ri->pseg)); + 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) @@ -623,7 +627,7 @@ nandfs_search_super_root(struct nandfs_d (uintmax_t)ri->pseg)); for (;;) { - error = nandfs_load_segsum(nandfsdev, ri); + error = nandfs_load_segsum_ri(nandfsdev, ri); if (error) break; @@ -923,211 +927,6 @@ nandfs_lookup_name_in_dir(struct vnode * return (error); } -static int -nandfs_process_bdesc(struct nandfs_device *nffsdev, struct nandfs_bdesc *bd, - uint64_t nmembs) -{ - struct nandfs_node *dat_node; - struct buf *bp; - uint64_t i; - int error; - - dat_node = nffsdev->nd_dat_node; - - VOP_LOCK(NTOV(dat_node), LK_EXCLUSIVE); - - for (i = 0; i < nmembs; i++) { - DPRINTF(CLEAN, ("%s: idx %jx offset %jx\n", - __func__, i, bd[i].bd_offset)); - if (bd[i].bd_level) { - error = nandfs_bread_meta(dat_node, bd[i].bd_offset, *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***