Ejemplo n.º 1
0
int
nandfs_get_seg_stat(struct nandfs_device *nandfsdev,
    struct nandfs_seg_stat *nss)
{
	struct nandfs_sufile_header *suhdr;
	struct nandfs_node *su_node;
	struct buf *bp;
	int err;

	su_node = nandfsdev->nd_su_node;

	NANDFS_WRITELOCK(nandfsdev);
	VOP_LOCK(NTOV(su_node), LK_SHARED);
	err = nandfs_bread(nandfsdev->nd_su_node, 0, NOCRED, 0, &bp);
	if (err) {
		brelse(bp);
		VOP_UNLOCK(NTOV(su_node), 0);
		NANDFS_WRITEUNLOCK(nandfsdev);
		return (-1);
	}

	suhdr = (struct nandfs_sufile_header *)bp->b_data;
	nss->nss_nsegs = nandfsdev->nd_fsdata.f_nsegments;
	nss->nss_ncleansegs = suhdr->sh_ncleansegs;
	nss->nss_ndirtysegs = suhdr->sh_ndirtysegs;
	nss->nss_ctime = 0;
	nss->nss_nongc_ctime = nandfsdev->nd_ts.tv_sec;
	nss->nss_prot_seq = nandfsdev->nd_seg_sequence;

	brelse(bp);
	VOP_UNLOCK(NTOV(su_node), 0);

	NANDFS_WRITEUNLOCK(nandfsdev);

	return (0);
}
Ejemplo n.º 2
0
static int
nandfs_cleaner_body(struct nandfs_device *fsdev, uint64_t *rseg)
{
	struct nandfs_vinfo *vinfo, *vip, *vipi;
	struct nandfs_bdesc *bdesc, *bdp, *bdpi;
	struct nandfs_cpstat cpstat;
	struct nandfs_cpinfo *cpinfo = NULL;
	uint64_t *segnums, *segp;
	int select, selected;
	int error = 0;
	int nsegs;
	int i;

	nsegs = nandfs_cleaner_segments;

	vip = vinfo = malloc(sizeof(*vinfo) *
	    fsdev->nd_fsdata.f_blocks_per_segment * nsegs, M_NANDFSTEMP,
	    M_ZERO | M_WAITOK);
	bdp = bdesc = malloc(sizeof(*bdesc) *
	    fsdev->nd_fsdata.f_blocks_per_segment * nsegs, M_NANDFSTEMP,
	    M_ZERO | M_WAITOK);
	segp = segnums = malloc(sizeof(*segnums) * nsegs, M_NANDFSTEMP,
	    M_WAITOK);

	error = nandfs_cleaner_choose_segment(fsdev, &segp, nsegs, rseg);
	if (error) {
		nandfs_error("%s:%d", __FILE__, __LINE__);
		goto out;
	}

	if (segnums == segp)
		goto out;

	selected = 0;
	for (i = 0; i < segp - segnums; i++) {
		error = nandfs_cleaner_iterate_segment(fsdev, segnums[i], &vip,
		    &bdp, &select);
		if (error) {
			/*
			 * XXX deselect (see below)?
			 */
			goto out;
		}
		if (!select)
			segnums[i] = NANDFS_NOSEGMENT;
		else {
			error = nandfs_markgc_segment(fsdev, segnums[i]);
			if (error) {
				nandfs_error("%s:%d\n", __FILE__, __LINE__);
				goto out;
			}
			selected++;
		}
	}

	if (selected == 0) {
		MPASS(vinfo == vip);
		MPASS(bdesc == bdp);
		goto out;
	}

	error = nandfs_get_cpstat(fsdev->nd_cp_node, &cpstat);
	if (error) {
		nandfs_error("%s:%d\n", __FILE__, __LINE__);
		goto out;
	}

	if (cpstat.ncp_nss != 0) {
		cpinfo = malloc(sizeof(struct nandfs_cpinfo) * cpstat.ncp_nss,
		    M_NANDFSTEMP, M_WAITOK);
		error = nandfs_get_cpinfo(fsdev->nd_cp_node, 1, NANDFS_SNAPSHOT,
		    cpinfo, cpstat.ncp_nss, NULL);
		if (error) {
			nandfs_error("%s:%d\n", __FILE__, __LINE__);
			goto out_locked;
		}
	}

	NANDFS_WRITELOCK(fsdev);
	DPRINTF(CLEAN, ("%s: got lock\n", __func__));

	error = nandfs_get_dat_vinfo(fsdev, vinfo, vip - vinfo);
	if (error) {
		nandfs_error("%s:%d\n", __FILE__, __LINE__);
		goto out_locked;
	}

	nandfs_cleaner_vinfo_mark_alive(fsdev, vinfo, vip - vinfo, cpinfo,
	    cpstat.ncp_nss);

	error = nandfs_get_dat_bdescs(fsdev, bdesc, bdp - bdesc);
	if (error) {
		nandfs_error("%s:%d\n", __FILE__, __LINE__);
		goto out_locked;
	}

	nandfs_cleaner_bdesc_mark_alive(fsdev, bdesc, bdp - bdesc);

	DPRINTF(CLEAN, ("got:\n"));
	for (vipi = vinfo; vipi < vip; vipi++) {
		DPRINTF(CLEAN, ("v ino %jx vblocknr %jx start %jx end %jx "
		    "alive %d\n", vipi->nvi_ino, vipi->nvi_vblocknr,
		    vipi->nvi_start, vipi->nvi_end, vipi->nvi_alive));
	}
	for (bdpi = bdesc; bdpi < bdp; bdpi++) {
		DPRINTF(CLEAN, ("b oblocknr %jx blocknr %jx offset %jx "
		    "alive %d\n", bdpi->bd_oblocknr, bdpi->bd_blocknr,
		    bdpi->bd_offset, bdpi->bd_alive));
	}
	DPRINTF(CLEAN, ("end list\n"));

	error = nandfs_cleaner_clean_segments(fsdev, vinfo, vip - vinfo, NULL,
	    0, bdesc, bdp - bdesc, segnums, segp - segnums);
	if (error)
		nandfs_error("%s:%d\n", __FILE__, __LINE__);

out_locked:
	NANDFS_WRITEUNLOCK(fsdev);
out:
	free(cpinfo, M_NANDFSTEMP);
	free(segnums, M_NANDFSTEMP);
	free(bdesc, M_NANDFSTEMP);
	free(vinfo, M_NANDFSTEMP);

	return (error);
}