svn commit: r233981 - projects/nand/sys/fs/nandfs

Grzegorz Bernacki gber at FreeBSD.org
Sat Apr 7 05:17:42 UTC 2012


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 <sys/uuid.h>
+
 #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 ***


More information about the svn-src-projects mailing list