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