ssize_t nandfs_get_cp(struct nandfs *fs, uint64_t cno, struct nandfs_cpinfo *cpinfo, size_t nci) { return (nandfs_get_cpinfo(fs, cno, NANDFS_CHECKPOINT, cpinfo, nci)); }
ssize_t nandfs_get_snap(struct nandfs *fs, uint64_t cno, struct nandfs_cpinfo *cpinfo, size_t nci) { return (nandfs_get_cpinfo(fs, cno, NANDFS_SNAPSHOT, cpinfo, nci)); }
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); }