コード例 #1
0
ファイル: trim_map.c プロジェクト: ChaosJohn/freebsd
static void
trim_map_segment_remove(trim_map_t *tm, trim_seg_t *ts, uint64_t start,
    uint64_t end)
{
	trim_seg_t *nts;
	boolean_t left_over, right_over;

	ASSERT(MUTEX_HELD(&tm->tm_lock));

	left_over = (ts->ts_start < start);
	right_over = (ts->ts_end > end);

	TRIM_MAP_SDEC(tm, end - start);
	if (left_over && right_over) {
		nts = kmem_alloc(sizeof (*nts), KM_SLEEP);
		nts->ts_start = end;
		nts->ts_end = ts->ts_end;
		nts->ts_txg = ts->ts_txg;
		nts->ts_time = ts->ts_time;
		ts->ts_end = start;
		avl_insert_here(&tm->tm_queued_frees, nts, ts, AVL_AFTER);
		list_insert_after(&tm->tm_head, ts, nts);
		TRIM_MAP_QINC(tm);
	} else if (left_over) {
		ts->ts_end = start;
	} else if (right_over) {
		ts->ts_start = end;
	} else {
		avl_remove(&tm->tm_queued_frees, ts);
		list_remove(&tm->tm_head, ts);
		TRIM_MAP_QDEC(tm);
		kmem_free(ts, sizeof (*ts));
	}
}
コード例 #2
0
ファイル: range_tree.c プロジェクト: Alkzndr/freebsd
void
range_tree_remove(void *arg, uint64_t start, uint64_t size)
{
	range_tree_t *rt = arg;
	avl_index_t where;
	range_seg_t rsearch, *rs, *newseg;
	uint64_t end = start + size;
	boolean_t left_over, right_over;

	ASSERT(MUTEX_HELD(rt->rt_lock));
	VERIFY3U(size, !=, 0);
	VERIFY3U(size, <=, rt->rt_space);

	rsearch.rs_start = start;
	rsearch.rs_end = end;
	rs = avl_find(&rt->rt_root, &rsearch, &where);

	/* Make sure we completely overlap with someone */
	if (rs == NULL) {
		zfs_panic_recover("zfs: freeing free segment "
		    "(offset=%llu size=%llu)",
		    (longlong_t)start, (longlong_t)size);
		return;
	}
	VERIFY3U(rs->rs_start, <=, start);
	VERIFY3U(rs->rs_end, >=, end);

	left_over = (rs->rs_start != start);
	right_over = (rs->rs_end != end);

	range_tree_stat_decr(rt, rs);

	if (rt->rt_ops != NULL)
		rt->rt_ops->rtop_remove(rt, rs, rt->rt_arg);

	if (left_over && right_over) {
		newseg = kmem_cache_alloc(range_seg_cache, KM_SLEEP);
		newseg->rs_start = end;
		newseg->rs_end = rs->rs_end;
		range_tree_stat_incr(rt, newseg);

		rs->rs_end = start;

		avl_insert_here(&rt->rt_root, newseg, rs, AVL_AFTER);
		if (rt->rt_ops != NULL)
			rt->rt_ops->rtop_add(rt, newseg, rt->rt_arg);
	} else if (left_over) {
		rs->rs_end = start;
	} else if (right_over) {
		rs->rs_start = end;
	} else {
		avl_remove(&rt->rt_root, rs);
		kmem_cache_free(range_seg_cache, rs);
		rs = NULL;
	}

	if (rs != NULL) {
		range_tree_stat_incr(rt, rs);

		if (rt->rt_ops != NULL)
			rt->rt_ops->rtop_add(rt, rs, rt->rt_arg);
	}

	rt->rt_space -= size;
}
コード例 #3
0
ファイル: pkgserv.c プロジェクト: AlfredArouna/illumos-gate
static void
parse_contents(void)
{
	int cnt;
	pkgentry_t *ent, *e2;
	avl_index_t where;
	int num = 0;
	struct stat stb;
	ptrdiff_t off;
	char *p, *q, *map;
	pkgentry_t *lastentry = NULL;
	int d;
	int cntserrs = 0;

	cnt = open(CONTENTS, O_RDONLY);

	cind = 0;

	if (cnt == -1) {
		if (errno == ENOENT)
			return;
		exit(99);
	}

	if (fstat(cnt, &stb) != 0) {
		(void) close(cnt);
		exit(99);
	}
	if (stb.st_size == 0) {
		(void) close(cnt);
		return;
	}

	map = mmap(0, stb.st_size, PROT_READ, MAP_PRIVATE, cnt, 0);
	(void) close(cnt);
	if (map == (char *)-1)
		return;

	(void) madvise(map, stb.st_size, MADV_WILLNEED);

	for (off = 0; off < stb.st_size; off += q - p) {
		p = map + off;
		q = memchr(p, '\n', stb.st_size - off);
		if (q == NULL)
			break;

		q++;
		num++;
		if (p[0] == '#' || p[0] == '\n') {
			handle_comments(p, q - p);
			continue;
		}
		ent = parse_line(p, q - p - 1, B_TRUE);

		if (ent == NULL) {
			cntserrs++;
			continue;
		}

		/*
		 * We save time by assuming the database is sorted; by
		 * using avl_insert_here(), building the tree is nearly free.
		 * lastentry always contains the last entry in the AVL tree.
		 */
		if (lastentry == NULL) {
			avl_add(list, ent);
			lastentry = ent;
		} else if ((d = avlcmp(ent, lastentry)) == 1) {
			avl_insert_here(list, ent, lastentry, AVL_AFTER);
			lastentry = ent;
		} else if (d == 0 ||
		    (e2 = avl_find(list, ent, &where)) != NULL) {
			/*
			 * This can only happen if the contents file is bad;
			 * this can, e.g., happen with the old SQL contents DB,
			 * it didn't sort properly.  Assume the first one
			 * is the correct one, but who knows?
			 */
			if (d == 0)
				e2 = lastentry;
			if (strcmp(ent->line, e2->line) != 0) {
				progerr(gettext("two entries for %.*s"),
				    ent->pathlen, ent->line);
				cntserrs++;
			}
			freeentry(ent);
		} else {
			/* Out of order: not an error for us, really. */
			progerr(gettext("bad read of contents file"));
			logerr(gettext("pathname: Unknown"));
			logerr(gettext(
			    "problem: unable to read pathname field"));
			if (one_shot)
				exit(2);
			avl_insert(list, ent, where);
		}
	}

	cind = 0;

	(void) munmap(map, stb.st_size);

	/* By default, we ignore bad lines, keep them in a copy. */
	if (cntserrs > 0 && stb.st_nlink == 1) {
		char bcf[sizeof (BADCONTENTS)];

		(void) strcpy(bcf, BADCONTENTS);
		if (mktemp(bcf) != NULL) {
			(void) link(CONTENTS, bcf);
			syslog(LOG_WARNING, "A bad contents file was saved: %s",
			    bcf);
		}
	}
}