示例#1
0
/*
 * helper function used by traverse tree to start tree traversal not from the
 * tree root, but from @h->object's vroot, if possible.
 */
static int prepare_object_lookup(cbk_handle * h)
{
	znode *vroot;
	int result;

	vroot = inode_get_vroot(h->object);
	if (vroot == NULL) {
		/*
		 * object doesn't have known vroot, start from real tree root.
		 */
		return LOOKUP_CONT;
	}

	h->level = znode_get_level(vroot);
	/* take a long-term lock on vroot */
	h->result = longterm_lock_znode(h->active_lh, vroot,
					cbk_lock_mode(h->level, h),
					ZNODE_LOCK_LOPRI);
	result = LOOKUP_REST;
	if (h->result == 0) {
		int isunique;
		int inside;

		isunique = h->flags & CBK_UNIQUE;
		/* check that key is inside vroot */
		read_lock_dk(h->tree);
		inside = (znode_contains_key_strict(vroot, h->key, isunique) &&
			  !ZF_ISSET(vroot, JNODE_HEARD_BANSHEE));
		read_unlock_dk(h->tree);
		if (inside) {
			h->result = zload(vroot);
			if (h->result == 0) {
				/* search for key in vroot. */
				result = cbk_node_lookup(h);
				zrelse(vroot);	/*h->active_lh->node); */
				if (h->active_lh->node != vroot) {
					result = LOOKUP_REST;
				} else if (result == LOOKUP_CONT) {
					move_lh(h->parent_lh, h->active_lh);
					h->flags &= ~CBK_DKSET;
				}
			}
		}
	}

	zput(vroot);

	if (IS_CBKERR(h->result) || result == LOOKUP_REST)
		hput(h);
	return result;
}
/**
 * find_start
 * @inode:
 * @id:
 * @offset:
 *
 * this is used by tail2extent and extent2tail to detect where previous
 * uncompleted conversion stopped
 */
static int find_start(struct inode *inode, reiser4_plugin_id id, __u64 *offset)
{
	int result;
	lock_handle lh;
	coord_t coord;
	struct unix_file_info *ufo;
	int found;
	reiser4_key key;

	ufo = unix_file_inode_data(inode);
	init_lh(&lh);
	result = 0;
	found = 0;
	inode_file_plugin(inode)->key_by_inode(inode, *offset, &key);
	do {
		init_lh(&lh);
		result = find_file_item_nohint(&coord, &lh, &key,
					       ZNODE_READ_LOCK, inode);

		if (result == CBK_COORD_FOUND) {
			if (coord.between == AT_UNIT) {
				/*coord_clear_iplug(&coord); */
				result = zload(coord.node);
				if (result == 0) {
					if (item_id_by_coord(&coord) == id)
						found = 1;
					else
						item_plugin_by_coord(&coord)->s.
						    file.append_key(&coord,
								    &key);
					zrelse(coord.node);
				}
			} else
				result = RETERR(-ENOENT);
		}
		done_lh(&lh);
	} while (result == 0 && !found);
	*offset = get_key_offset(&key);
	return result;
}
/**
 * tail2extent
 * @uf_info:
 *
 *
 */
int tail2extent(struct unix_file_info *uf_info)
{
	int result;
	reiser4_key key;	/* key of next byte to be moved to page */
	char *p_data;		/* data of page */
	unsigned page_off = 0,	/* offset within the page where to copy data */
	    count;		/* number of bytes of item which can be
				 * copied to page */
	struct page *pages[TAIL2EXTENT_PAGE_NUM];
	struct page *page;
	int done;		/* set to 1 when all file is read */
	char *item;
	int i;
	struct inode *inode;
	int first_iteration;
	int bytes;
	__u64 offset;

	assert("nikita-3362", ea_obtained(uf_info));
	inode = unix_file_info_to_inode(uf_info);
	assert("nikita-3412", !IS_RDONLY(inode));
	assert("vs-1649", uf_info->container != UF_CONTAINER_EXTENTS);
	assert("", !reiser4_inode_get_flag(inode, REISER4_PART_IN_CONV));

	offset = 0;
	first_iteration = 1;
	result = 0;
	if (reiser4_inode_get_flag(inode, REISER4_PART_MIXED)) {
		/*
		 * file is marked on disk as there was a conversion which did
		 * not complete due to either crash or some error. Find which
		 * offset tail conversion stopped at
		 */
		result = find_start(inode, FORMATTING_ID, &offset);
		if (result == -ENOENT) {
			/* no tail items found, everything is converted */
			uf_info->container = UF_CONTAINER_EXTENTS;
			complete_conversion(inode);
			return 0;
		} else if (result != 0)
			/* some other error */
			return result;
		first_iteration = 0;
	}

	reiser4_inode_set_flag(inode, REISER4_PART_IN_CONV);

	/* get key of first byte of a file */
	inode_file_plugin(inode)->key_by_inode(inode, offset, &key);

	done = 0;
	while (done == 0) {
		memset(pages, 0, sizeof(pages));
		result = reserve_tail2extent_iteration(inode);
		if (result != 0) {
			reiser4_inode_clr_flag(inode, REISER4_PART_IN_CONV);
			goto out;
		}
		if (first_iteration) {
			reiser4_inode_set_flag(inode, REISER4_PART_MIXED);
			reiser4_update_sd(inode);
			first_iteration = 0;
		}
		bytes = 0;
		for (i = 0; i < sizeof_array(pages) && done == 0; i++) {
			assert("vs-598",
			       (get_key_offset(&key) & ~PAGE_CACHE_MASK) == 0);
			page = alloc_page(reiser4_ctx_gfp_mask_get());
			if (!page) {
				result = RETERR(-ENOMEM);
				goto error;
			}

			page->index =
			    (unsigned long)(get_key_offset(&key) >>
					    PAGE_CACHE_SHIFT);
			/*
			 * usually when one is going to longterm lock znode (as
			 * find_file_item does, for instance) he must not hold
			 * locked pages. However, there is an exception for
			 * case tail2extent. Pages appearing here are not
			 * reachable to everyone else, they are clean, they do
			 * not have jnodes attached so keeping them locked do
			 * not risk deadlock appearance
			 */
			assert("vs-983", !PagePrivate(page));
			reiser4_invalidate_pages(inode->i_mapping, page->index,
						 1, 0);

			for (page_off = 0; page_off < PAGE_CACHE_SIZE;) {
				coord_t coord;
				lock_handle lh;

				/* get next item */
				/* FIXME: we might want to readahead here */
				init_lh(&lh);
				result =
				    find_file_item_nohint(&coord, &lh, &key,
							  ZNODE_READ_LOCK,
							  inode);
				if (result != CBK_COORD_FOUND) {
					/*
					 * error happened of not items of file
					 * were found
					 */
					done_lh(&lh);
					page_cache_release(page);
					goto error;
				}

				if (coord.between == AFTER_UNIT) {
					/*
					 * end of file is reached. Padd page
					 * with zeros
					 */
					done_lh(&lh);
					done = 1;
					p_data = kmap_atomic(page, KM_USER0);
					memset(p_data + page_off, 0,
					       PAGE_CACHE_SIZE - page_off);
					kunmap_atomic(p_data, KM_USER0);
					break;
				}

				result = zload(coord.node);
				if (result) {
					page_cache_release(page);
					done_lh(&lh);
					goto error;
				}
				assert("vs-856", coord.between == AT_UNIT);
				item = ((char *)item_body_by_coord(&coord)) +
					coord.unit_pos;

				/* how many bytes to copy */
				count =
				    item_length_by_coord(&coord) -
				    coord.unit_pos;
				/* limit length of copy to end of page */
				if (count > PAGE_CACHE_SIZE - page_off)
					count = PAGE_CACHE_SIZE - page_off;

				/*
				 * copy item (as much as will fit starting from
				 * the beginning of the item) into the page
				 */
				p_data = kmap_atomic(page, KM_USER0);
				memcpy(p_data + page_off, item, count);
				kunmap_atomic(p_data, KM_USER0);

				page_off += count;
				bytes += count;
				set_key_offset(&key,
					       get_key_offset(&key) + count);

				zrelse(coord.node);
				done_lh(&lh);
			} /* end of loop which fills one page by content of
			   * formatting items */

			if (page_off) {
				/* something was copied into page */
				pages[i] = page;
			} else {
				page_cache_release(page);
				assert("vs-1648", done == 1);
				break;
			}
		} /* end of loop through pages of one conversion iteration */

		if (i > 0) {
			result = replace(inode, pages, i, bytes);
			release_all_pages(pages, sizeof_array(pages));
			if (result)
				goto error;
			/*
			 * We have to drop exclusive access to avoid deadlock
			 * which may happen because called by reiser4_writepages
			 * capture_unix_file requires to get non-exclusive
			 * access to a file. It is safe to drop EA in the middle
			 * of tail2extent conversion because write_unix_file,
			 * setattr_unix_file(truncate), mmap_unix_file,
			 * release_unix_file(extent2tail) checks if conversion
			 * is not in progress (see comments before
			 * get_exclusive_access_careful().
			 * Other processes that acquire non-exclusive access
			 * (read_unix_file, reiser4_writepages, etc) should work
			 * on partially converted files.
			 */
			drop_exclusive_access(uf_info);
			/* throttle the conversion
			   FIXME-EDWARD: Pass the precise number of pages
			   that was dirtied */
			reiser4_throttle_write(inode, 1);
			get_exclusive_access(uf_info);

			/*
			 * nobody is allowed to complete conversion but a
			 * process which started it
			 */
			assert("", reiser4_inode_get_flag(inode,
							  REISER4_PART_MIXED));
		}
	}
	if (result == 0) {
		/* file is converted to extent items */
		reiser4_inode_clr_flag(inode, REISER4_PART_IN_CONV);
		assert("vs-1697", reiser4_inode_get_flag(inode,
							 REISER4_PART_MIXED));

		uf_info->container = UF_CONTAINER_EXTENTS;
		complete_conversion(inode);
	} else {
		/*
		 * conversion is not complete. Inode was already marked as
		 * REISER4_PART_MIXED and stat-data were updated at the first
		 * iteration of the loop above.
		 */
	error:
		release_all_pages(pages, sizeof_array(pages));
		reiser4_inode_clr_flag(inode, REISER4_PART_IN_CONV);
		warning("edward-1548", "Partial conversion of %llu: %i",
			(unsigned long long)get_inode_oid(inode), result);
	}

 out:
	/* this flag should be cleared, otherwise get_exclusive_access_careful()
	   will fall into infinite loop */
	assert("edward-1549", !reiser4_inode_get_flag(inode,
						      REISER4_PART_IN_CONV));
	return result;
}
示例#4
0
文件: test.c 项目: maandree/libzahl
int
main(void)
{
	/* static because otherwise it would have to be volatile yeilding a lot of stupid
	 * warnings. auto variables are not guaranteed to be readable after a long jump. */
	static z_t a, b, c, d, _0, _1, _2, _3;
	static char buf[2000];
	static int ret = 0;
	static jmp_buf env, env2;
	static size_t n;

#define BUF_N (sizeof(buf) - 1)

	if (setjmp(env)) {
		zperror(0);
		ret = 2;
		goto done;
	}

	zsetup(env);
	zinit(a), zinit(b), zinit(c), zinit(d), zinit(_0), zinit(_1), zinit(_2), zinit(_3);

	zsetu(_0, 0);
	zsetu(_1, 1);
	zsetu(_2, 2);
	zsetu(_3, 3);

	assert(zeven(_0), == 1);
	assert(zodd(_0), == 0);
	assert(zzero(_0), == 1);
	assert(zsignum(_0), == 0);
	assert(zeven(_1), == 0);
	assert(zodd(_1), == 1);
	assert(zzero(_1), == 0);
	assert(zsignum(_1), == 1);
	assert(zeven(_2), == 1);
	assert(zodd(_2), == 0);
	assert(zzero(_2), == 0);
	assert(zsignum(_2), == 1);

	zswap(_1, _2);
	assert(zeven(_2), == 0);
	assert(zodd(_2), == 1);
	assert(zzero(_2), == 0);
	assert(zsignum(_2), == 1);
	assert(zeven(_1), == 1);
	assert(zodd(_1), == 0);
	assert(zzero(_1), == 0);
	assert(zsignum(_1), == 1);
	zswap(_2, _1);
	assert(zeven(_1), == 0);
	assert(zodd(_1), == 1);
	assert(zzero(_1), == 0);
	assert(zsignum(_1), == 1);
	assert(zeven(_2), == 1);
	assert(zodd(_2), == 0);
	assert(zzero(_2), == 0);
	assert(zsignum(_2), == 1);

	assert((zneg(_2, _2), zsignum(_2)), == -1); zneg(_2, _2);
	assert(zsignum(_2), == 1);

	assert(zcmp(_0, _0), == 0);
	assert(zcmp(_1, _1), == 0);
	assert(zcmp(_0, _1), < 0);
	assert(zcmp(_1, _0), > 0);
	assert(zcmp(_1, _2), < 0);
	assert(zcmp(_2, _1), > 0);
	assert(zcmp(_0, _2), < 0);
	assert(zcmp(_2, _0), > 0);

	zbset(a, _0, 0, 1);
	assert(zcmp(a, _1), == 0);
	zbset(a, a, 1, 1);
	assert(zcmp(a, _3), == 0);
	zbset(a, a, 0, 0);
	assert(zcmp(a, _2), == 0);
	zbset(a, a, 0, 0);
	assert(zcmp(a, _2), == 0);
	zbset(a, a, 0, -1);
	assert(zcmp(a, _3), == 0);
	zbset(a, a, 0, -1);
	assert(zcmp(a, _2), == 0);

	zadd(a, _0, _1);
	assert(zsignum(a), == 1);
	assert(zcmp(a, _1), == 0);
	assert(zcmpi(a, 1), == 0);
	assert(zcmpu(a, 1), == 0);
	zneg(a, a);
	assert(zsignum(a), == -1);
	assert(zcmp(a, _1), < 0);
	assert(zcmpi(a, 1), < 0);
	assert(zcmpu(a, 1), < 0);
	zadd(a, _2, _0);
	assert(zsignum(a), == 1);
	assert(zcmp(a, _2), == 0);
	assert(zcmpi(a, 2), == 0);
	assert(zcmpu(a, 2), == 0);
	zneg(a, a);
	assert(zsignum(a), == -1);
	assert(zcmp(a, _2), < 0);
	assert(zcmpi(a, 2), < 0);
	assert(zcmpu(a, 2), < 0);
	assert(zsignum(_1), == 1);
	zadd(a, _1, _1);
	assert(zsignum(a), == 1);
	assert(zcmp(a, _2), == 0);
	assert(zcmpi(a, 2), == 0);
	assert(zcmpu(a, 2), == 0);
	zset(b, _1);
	zadd(a, b, _1);
	assert(zsignum(a), == 1);
	assert(zcmp(a, _2), == 0);
	assert(zcmpi(a, 2), == 0);
	assert(zcmpu(a, 2), == 0);
	zneg(a, a);
	zset(b, _2);
	zneg(b, b);
	assert(zsignum(a), == -1);
	assert(zcmp(a, b), == 0);
	assert(zcmp(a, _2), < 0);
	assert(zcmpmag(a, b), == 0);
	assert(zcmpmag(a, _2), == 0);
	assert(zcmpi(a, 2), < 0);
	assert(zcmpu(a, 2), < 0);
	assert(zcmpi(a, -2), == 0);
	assert((zneg(_2, _2), zcmp(a, _2)), == 0); zneg(_2, _2);
	zadd(a, _1, _2);
	assert(zsignum(a), == 1);
	assert(zcmp(a, _2), > 0);
	assert(zcmpi(a, 2), > 0);
	assert(zcmpu(a, 2), > 0);
	zneg(a, a);
	zset(b, _2);
	zneg(b, b);
	assert(zsignum(a), == -1);
	assert(zcmpmag(a, _2), > 0);
	assert(zcmpmag(a, b), > 0);
	assert(zcmp(a, b), < 0);
	assert(zcmp(a, _2), < 0);
	assert(zcmpi(a, 2), < 0);
	assert(zcmpu(a, 2), < 0);
	assert(zcmpi(a, -2), < 0);
	assert((zneg(_2, _2), zcmp(a, _2)), < 0); zneg(_2, _2);
	zneg(b, _3);
	assert(zcmp(a, b), == 0);

	zunsetup();
	zsetup(env);

	zsub(a, _2, _1);
	assert(zcmpmag(_2, _1), > 0);
	assert(zcmpmag(_2, _0), > 0);
	assert(zcmpmag(_1, _0), > 0);
	zsub(b, _1, _2);
	assert(zcmpmag(_2, _0), > 0);
	assert(zcmpmag(_1, _0), > 0);
	assert(zcmpmag(_2, _1), > 0);
	assert(zcmpmag(a, b), == 0);
	assert(zcmpmag(a, _1), == 0);
	assert(zcmp(a, b), > 0);
	assert(zcmp(a, _1), == 0);
	assert(zcmp(b, _1), < 0);
	zsub(a, _1, _1);
	assert(zcmp(a, _0), == 0);
	zseti(b, 0);
	zsetu(c, 0);
	zsub(a, b, c);
	assert(zcmp(a, _0), == 0);
	assert(zcmpmag(_2, _1), > 0);
	assert(zcmp(_2, _1), > 0);
	zsub(a, _2, _1);
	assert(zsignum(a), == 1);
	assert(zcmpmag(a, _1), == 0);
	assert(zcmp(a, _1), == 0);
	zsub(a, a, _1);
	assert(zcmp(a, _0), == 0);
	zsub(a, a, _0);
	assert(zcmp(a, _0), == 0);
	zsub(a, _1, _2);
	assert(zcmp(a, _1), < 0);
	assert(zcmpmag(a, _1), == 0);
	zabs(a, a);
	assert(zcmp(a, _1), == 0);
	zabs(a, a);
	assert(zcmp(a, _1), == 0);
	zabs(a, _1);
	assert(zcmp(a, _1), == 0);
	zabs(a, _0);
	assert(zcmp(a, _0), == 0);

	zseti(b, -1);
	zseti(c, -2);
	zadd(a, _0, b);
	assert(zcmp(a, _0), < 0);
	assert(zcmpi(a, -1), == 0);
	assert(zcmpmag(a, _1), == 0);
	assert(zcmp(a, _1), < 0);
	zadd(a, b, _0);
	assert(zcmp(a, _0), < 0);
	assert(zcmpi(a, -1), == 0);
	assert(zcmpmag(a, _1), == 0);
	assert(zcmp(a, _1), < 0);
	zadd(a, b, c);
	assert(zcmp(a, c), < 0);
	assert(zcmpmag(a, _2), > 0);
	zadd(a, c, b);
	assert(zcmp(a, c), < 0);
	assert(zcmpmag(a, _2), > 0);
	zadd(a, b, _1);
	assert(zcmp(a, _0), == 0);
	assert(zcmpmag(a, _0), == 0);
	zadd(a, _1, b);
	assert(zcmp(a, _0), == 0);
	assert(zcmpmag(a, _0), == 0);

	zneg(b, _1);
	zneg(c, _2);
	zsub(a, _0, b);
	assert(zcmp(a, _1), == 0);
	zsub(a, b, _0);
	assert(zcmpmag(a, _1), == 0);
	assert(zcmp(a, _1), < 0);
	zsub(a, b, c);
	assert(zcmpmag(a, _1), == 0);
	assert(zcmp(a, _1), == 0);
	zsub(a, c, b);
	assert(zcmpmag(a, _1), == 0);
	assert(zcmp(a, _1), < 0);
	zsub(a, b, _1);
	assert(zcmpmag(a, _2), == 0);
	assert(zcmp(a, _2), < 0);
	assert(zcmp(a, c), == 0);
	zsub(a, _1, b);
	assert(zcmp(b, _1), < 0);
	assert(zcmpmag(b, _1), == 0);
	assert(zcmp(a, _2), == 0);

	zsetu(a, 1000);
	zsetu(b, 0);
	assert(zcmp(a, b), != 0);
	n = zsave(a, buf);
	assert(n > 0, > 0);
	assert_zu(zload(b, buf), n);
	assert(zcmp(a, b), == 0);

	zneg(b, _1);
	zneg(c, _2);

	assert((zadd_unsigned(a, _1, _2), zcmp(a, _3)), == 0);
	assert((zadd_unsigned(a, b, c), zcmp(a, _3)), == 0);
	assert((zadd_unsigned(a, b, _2), zcmp(a, _3)), == 0);
	assert((zadd_unsigned(a, _1, c), zcmp(a, _3)), == 0);

	assert((zadd_unsigned(a, _0, _0), zcmp(a, _0)), == 0);
	assert((zadd_unsigned(a, _0, _1), zcmp(a, _1)), == 0);
	assert((zadd_unsigned(a, _1, _1), zcmp(a, _2)), == 0);
	assert((zadd_unsigned(a, _1, _0), zcmp(a, _1)), == 0);
	zneg(_1, _1);
	assert((zadd_unsigned(a, _0, _0), zcmp(a, _0)), == 0);
	assert((zadd_unsigned(a, _0, _1), zcmp(a, _1)), != 0);
	assert((zadd_unsigned(a, _0, _1), zcmpmag(a, _1)), == 0);
	assert((zadd_unsigned(a, _1, _1), zcmp(a, _2)), == 0);
	assert((zadd_unsigned(a, _1, _0), zcmp(a, _1)), != 0);
	assert((zadd_unsigned(a, _1, _0), zcmpmag(a, _1)), == 0);
	zneg(_1, _1);

	assert((zsub_unsigned(a, _2, _1), zcmp(a, _1)), == 0);
	assert((zsub_unsigned(a, _2, b), zcmp(a, _1)), == 0);
	assert((zsub_unsigned(a, c, _1), zcmp(a, _1)), == 0);
	assert((zsub_unsigned(a, c, b), zcmp(a, _1)), == 0);

	assert((zsub_unsigned(a, _1, _2), zcmp(a, b)), == 0);
	assert((zsub_unsigned(a, b, _2), zcmp(a, b)), == 0);
	assert((zsub_unsigned(a, _1, c), zcmp(a, b)), == 0);
	assert((zsub_unsigned(a, b, c), zcmp(a, b)), == 0);

	assert_zu(zbits(_0), 1);
	assert_zu(zbits(_1), 1);
	assert_zu(zbits(_2), 2);
	assert_zu(zbits(_3), 2);

	assert_zu(zlsb(_0), SIZE_MAX);
	assert_zu(zlsb(_1), 0);
	assert_zu(zlsb(_2), 1);
	assert_zu(zlsb(_3), 0);

	assert((zand(a, _0, _0), zcmp(a, _0)), == 0);
	assert(zzero(a), == 1);
	assert((zand(a, _0, _1), zcmp(a, _0)), == 0);
	assert(zzero(a), == 1);
	assert((zand(a, _0, _2), zcmp(a, _0)), == 0);
	assert(zzero(a), == 1);
	assert((zand(a, _0, _3), zcmp(a, _0)), == 0);
	assert(zzero(a), == 1);
	assert((zand(a, _1, _1), zcmp(a, _1)), == 0);
	assert((zand(a, _1, _2), zcmp(a, _0)), == 0);
	assert(zzero(a), == 1);
	assert((zand(a, _1, _3), zcmp(a, _1)), == 0);
	assert((zand(a, _2, _2), zcmp(a, _2)), == 0);
	assert((zand(a, _2, _3), zcmp(a, _2)), == 0);
	assert((zand(a, _3, _3), zcmp(a, _3)), == 0);

	assert((zor(a, _0, _0), zcmp(a, _0)), == 0);
	assert(zzero(a), == 1);
	assert((zor(a, _0, _1), zcmp(a, _1)), == 0);
	assert((zor(a, _0, _2), zcmp(a, _2)), == 0);
	assert((zor(a, _0, _3), zcmp(a, _3)), == 0);
	assert((zor(a, _1, _1), zcmp(a, _1)), == 0);
	assert((zor(a, _1, _2), zcmp(a, _3)), == 0);
	assert((zor(a, _1, _3), zcmp(a, _3)), == 0);
	assert((zor(a, _2, _2), zcmp(a, _2)), == 0);
	assert((zor(a, _2, _3), zcmp(a, _3)), == 0);
	assert((zor(a, _3, _3), zcmp(a, _3)), == 0);

	assert((zxor(a, _0, _0), zcmp(a, _0)), == 0);
	assert(zzero(a), == 1);
	assert((zxor(a, _0, _1), zcmp(a, _1)), == 0);
	assert((zxor(a, _0, _2), zcmp(a, _2)), == 0);
	assert((zxor(a, _0, _3), zcmp(a, _3)), == 0);
	assert((zxor(a, _1, _1), zcmp(a, _0)), == 0);
	assert(zzero(a), == 1);
	assert((zxor(a, _1, _2), zcmp(a, _3)), == 0);
	assert((zxor(a, _1, _3), zcmp(a, _2)), == 0);
	assert((zxor(a, _2, _2), zcmp(a, _0)), == 0);
	assert(zzero(a), == 1);
	assert((zxor(a, _2, _3), zcmp(a, _1)), == 0);
	assert((zxor(a, _3, _3), zcmp(a, _0)), == 0);
	assert(zzero(a), == 1);

	zneg(b, _1);
	zneg(c, _3);
	zneg(_1, _1);
	zand(a, b, c);
	assert(zcmpmag(a, _1), == 0);
	assert(zcmp(a, _1), == 0);
	zneg(_1, _1);
	assert((zand(a, b, _3), zcmp(a, _1)), == 0);
	assert((zand(a, _1, c), zcmp(a, _1)), == 0);
	assert((zand(a, _0, c), zcmp(a, _0)), == 0);
	assert((zand(a, b, _0), zcmp(a, _0)), == 0);

	zneg(b, _1);
	zneg(c, _2);
	zneg(_3, _3);
	zor(a, b, c);
	assert(zcmpmag(a, _3), == 0);
	assert(zcmp(a, _3), == 0);
	zor(a, b, _2);
	assert(zcmpmag(a, _3), == 0);
	assert(zcmp(a, _3), == 0);
	zor(a, _1, c);
	assert((zcmpmag(a, _3)), == 0);
	assert((zcmp(a, _3)), == 0);
	assert((zor(a, _0, c), zcmp(a, c)), == 0);
	assert((zor(a, b, _0), zcmp(a, b)), == 0);
	zneg(_3, _3);

	zneg(b, _1);
	zneg(c, _2);
	zxor(a, b, c);
	assert(zcmpmag(a, _3), == 0);
	assert(zcmp(a, _3), == 0);
	zneg(_3, _3);
	zxor(a, b, _2);
	assert(zcmpmag(a, _3), == 0);
	assert(zcmp(a, _3), == 0);
	zxor(a, _1, c);
	assert(zcmpmag(a, _3), == 0);
	assert(zcmp(a, _3), == 0);
	zxor(a, b, _0);
	assert(zcmpmag(a, b), == 0);
	assert(zcmp(a, b), == 0);
	zxor(a, _0, c);
	assert(zcmpmag(a, c), == 0);
	assert(zcmp(a, c), == 0);
	zneg(_3, _3);

	assert((zlsh(a, _0, 0), zcmp(a, _0)), == 0);
	assert(zzero(a), == 1);
	assert((zlsh(a, _0, 1), zcmp(a, _0)), == 0);
	assert(zzero(a), == 1);
	assert((zlsh(a, _1, 0), zcmp(a, _1)), == 0);
	assert((zlsh(a, _1, 1), zcmp(a, _2)), == 0);
	assert((zlsh(a, _1, 2), zcmp(a, _2)), > 0);
	assert((zlsh(a, _2, 0), zcmp(a, _2)), == 0);
	assert((zlsh(a, _2, 1), zcmp(a, _2)), > 0);

	zset(a, _0);
	assert((zlsh(a, a, 0), zcmp(a, _0)), == 0);
	assert(zzero(a), == 1);
	assert((zlsh(a, a, 1), zcmp(a, _0)), == 0);
	assert(zzero(a), == 1);
	zset(a, _1);
	assert((zlsh(a, a, 0), zcmp(a, _1)), == 0);
	assert((zlsh(a, a, 1), zcmp(a, _2)), == 0);
	assert((zlsh(a, a, 2), zcmp(a, _2)), > 0);
	zset(a, _2);
	assert((zlsh(a, a, 0), zcmp(a, _2)), == 0);
	assert((zlsh(a, a, 1), zcmp(a, _2)), > 0);

	assert((zrsh(a, _0, 0), zcmp(a, _0)), == 0);
	assert(zzero(a), == 1);
	assert((zrsh(a, _0, 1), zcmp(a, _0)), == 0);
	assert(zzero(a), == 1);
	assert((zrsh(a, _1, 0), zcmp(a, _1)), == 0);
	assert((zrsh(a, _1, 1), zcmp(a, _0)), == 0);
	assert(zzero(a), == 1);
	assert((zrsh(a, _1, 2), zcmp(a, _0)), == 0);
	assert(zzero(a), == 1);
	assert((zrsh(a, _2, 0), zcmp(a, _2)), == 0);
	assert((zrsh(a, _2, 1), zcmp(a, _1)), == 0);
	assert((zrsh(a, _2, 2), zcmp(a, _0)), == 0);
	assert(zzero(a), == 1);

	zset(a, _0);
	assert((zrsh(a, a, 0), zcmp(a, _0)), == 0);
	assert(zzero(a), == 1);
	assert((zrsh(a, a, 1), zcmp(a, _0)), == 0);
	assert(zzero(a), == 1);
	zset(a, _1);
	assert((zrsh(a, a, 0), zcmp(a, _1)), == 0);
	assert((zrsh(a, a, 1), zcmp(a, _0)), == 0);
	assert(zzero(a), == 1);
	assert((zrsh(a, a, 2), zcmp(a, _0)), == 0);
	assert(zzero(a), == 1);
	zset(a, _2);
	assert((zrsh(a, a, 0), zcmp(a, _2)), == 0);
	assert((zrsh(a, a, 1), zcmp(a, _1)), == 0);
	assert((zrsh(a, a, 2), zcmp(a, _0)), == 0);
	assert(zzero(a), == 1);

	assert(zbtest(_0, 0), == 0);
	assert(zbtest(_1, 0), == 1);
	assert(zbtest(_2, 0), == 0);
	assert(zbtest(_3, 0), == 1);
	assert(zbtest(_0, 1), == 0);
	assert(zbtest(_1, 1), == 0);
	assert(zbtest(_2, 1), == 1);
	assert(zbtest(_3, 1), == 1);
	assert(zbtest(_0, 2), == 0);
	assert(zbtest(_1, 2), == 0);
	assert(zbtest(_2, 2), == 0);
	assert(zbtest(_3, 2), == 0);

	znot(a, _2);
	assert(zcmpmag(a, _1), == 0);
	assert(zcmp(a, _1), != 0);
	znot(a, a);
	assert(zcmp(a, _0), == 0);

	zsetu(a, 0x1234);
	zsetu(c, 0x234);
	ztrunc(a, a, 12);
	assert(zcmp(a, c), == 0);

	zsetu(a, 0xEEFF);
	zsetu(c, 0xEE);
	zsetu(d, 0xFF);
	zsplit(a, b, a, 8);
	assert(zcmpmag(a, c), == 0);
	assert(zcmpmag(b, d), == 0);
	zsetu(a, 0xEEFF);
	zsplit(b, a, a, 8);
	assert(zcmpmag(b, c), == 0);
	assert(zcmpmag(a, d), == 0);

	zmul(a, _2, _3);
	assert(zcmpi(a, 6), == 0);
	zneg(_3, _3);
	zmul(a, _2, _3);
	assert(zcmpi(a, -6), == 0);
	zneg(_3, _3);
	zneg(_2, _2);
	zmul(a, _2, _3);
	assert(zcmpi(a, -6), == 0);
	zneg(_3, _3);
	zmul(a, _2, _3);
	assert(zcmpi(a, 6), == 0);
	zneg(_3, _3);
	zneg(_2, _2);

	zmul(a, _3, _3);
	assert(zcmpi(a, 9), == 0);
	zsqr(a, _3);
	assert(zcmpi(a, 9), == 0);
	zneg(_3, _3);
	zmul(a, _3, _3);
	assert(zcmpi(a, 9), == 0);
	zsqr(a, _3);
	assert(zcmpi(a, 9), == 0);
	zneg(_3, _3);

	zseti(a, 8);
	zseti(b, 2);
	zdiv(c, a, b);
	assert(zcmpi(c, 4), == 0);
	zseti(b, -2);
	zdiv(c, a, b);
	assert(zcmpi(c, -4), == 0);
	zseti(a, -8);
	zseti(b, 2);
	zdiv(c, a, b);
	assert(zcmpi(c, -4), == 0);
	zseti(b, -2);
	zdiv(c, a, b);
	assert(zcmpi(c, 4), == 0);

	zseti(a, 1000);
	zseti(b, 10);
	zdiv(c, a, b);
	assert(zcmpi(c, 100), == 0);
	zseti(b, -10);
	zdiv(c, a, b);
	assert(zcmpi(c, -100), == 0);
	zseti(a, -1000);
	zseti(b, 10);
	zdiv(c, a, b);
	assert(zcmpi(c, -100), == 0);
	zseti(b, -10);
	zdiv(c, a, b);
	assert(zcmpi(c, 100), == 0);

	zseti(a, 7);
	zseti(b, 3);
	zmod(c, a, b);
	assert(zcmpi(c, 1), == 0);
	zseti(b, -3);
	zmod(c, a, b);
	assert(zcmpi(c, 1), == 0);
	zseti(a, -7);
	zseti(b, 3);
	zmod(c, a, b);
	assert(zcmpi(c, -1), == 0);
	zseti(b, -3);
	zmod(c, a, b);
	assert(zcmpi(c, -1), == 0);

	zseti(a, 7);
	zseti(b, 3);
	zdivmod(d, c, a, b);
	assert(zcmpi(d, 2), == 0);
	assert(zcmpi(c, 1), == 0);
	zseti(b, -3);
	zdivmod(d, c, a, b);
	assert(zcmpi(d, -2), == 0);
	assert(zcmpi(c, 1), == 0);
	zseti(a, -7);
	zseti(b, 3);
	zdivmod(d, c, a, b);
	assert(zcmpi(d, -2), == 0);
	assert(zcmpi(c, -1), == 0);
	zseti(b, -3);
	zdivmod(d, c, a, b);
	assert(zcmpi(d, 2), == 0);
	assert(zcmpi(c, -1), == 0);

	zseti(a, 10);
	zseti(b, -1);
	zpow(a, a, b);
	assert(zcmp(a, _0), == 0);

	zseti(a, 10);
	zseti(b, -1);
	zseti(a, 20);
	zmodpow(a, a, b, c);
	assert(zcmp(a, _0), == 0);

	zseti(a, 10);
	zseti(c, 100000L);
	zpowu(a, a, 5);
	assert(zcmpmag(a, c), == 0);
	assert(zcmp(a, c), == 0);

	zseti(a, -10);
	zseti(c, -100000L);
	zpowu(a, a, 5);
	assert(zcmpmag(a, c), == 0);
	assert(zcmp(a, c), == 0);

	zseti(a, -10);
	zseti(c, 10000L);
	zpowu(a, a, 4);
	assert(zcmpmag(a, c), == 0);
	assert(zcmp(a, c), == 0);

	zseti(a, 10);
	zseti(c, 3);
	zmodpowu(a, a, 5, c);
	assert(zcmpmag(a, _1), == 0);
	assert(zcmp(a, _1), == 0);

	zseti(a, 10);
	zseti(b, 5);
	zseti(c, 100000L);
	zpow(a, a, b);
	assert(zcmpmag(a, c), == 0);
	assert(zcmp(a, c), == 0);

	zseti(a, -10);
	zseti(b, 5);
	zseti(c, -100000L);
	zpow(a, a, b);
	assert(zcmpmag(a, c), == 0);
	assert(zcmp(a, c), == 0);

	zseti(a, -10);
	zseti(b, 4);
	zseti(c, 10000L);
	zpow(a, a, b);
	assert(zcmpmag(a, c), == 0);
	assert(zcmp(a, c), == 0);

	zseti(a, 10);
	zseti(b, 5);
	zseti(c, 3);
	zmodpow(a, a, b, c);
	assert(zcmpmag(a, _1), == 0);
	assert(zcmp(a, _1), == 0);

	zseti(a, 102);
	zseti(b, 501);
	zseti(c, 5);
	zmodmul(a, a, b, c);
	assert(zcmp(a, _2), == 0);

	zseti(b, 2 * 3 * 3 * 7);
	zseti(c, 3 * 7 * 11);
	zseti(d, 3 * 7);
	assert((zgcd(a, _0, _0), zcmp(a, _0)), == 0);
	assert((zgcd(a, b, _0), zcmp(a, b)), == 0);
	assert((zgcd(a, _0, c), zcmp(a, c)), == 0);
	assert((zgcd(a, b, b), zcmp(a, b)), == 0);
	assert((zgcd(a, b, _2), zcmp(a, _2)), == 0);
	assert((zgcd(a, _2, b), zcmp(a, _2)), == 0);
	assert((zgcd(a, _2, _2), zcmp(a, _2)), == 0);
	assert((zgcd(a, c, _2), zcmp(a, _1)), == 0);
	assert((zgcd(a, _2, c), zcmp(a, _1)), == 0);
	assert((zgcd(a, b, _1), zcmp(a, _1)), == 0);
	assert((zgcd(a, _1, c), zcmp(a, _1)), == 0);
	assert((zgcd(a, _1, _1), zcmp(a, _1)), == 0);
	assert((zgcd(a, b, c), zcmp(a, d)), == 0);
	assert((zgcd(a, c, b), zcmp(a, d)), == 0);

	zsets(a, "1234");
	assert(zcmpi(a, 1234), == 0);
	zsets(b, "+1234");
	assert(zcmp(a, b), == 0);
	assert_zu(zstr_length(_0, 10), 1);
	assert_zu(zstr_length(_1, 10), 1);
	assert_zu(zstr_length(_2, 10), 1);
	assert_zu(zstr_length(_3, 10), 1);
	zneg(_2, _2);
	assert_zu(zstr_length(_2, 10), 2);
	zneg(_2, _2);
	assert_zu(zstr_length(a, 10), 4);
	zstr(a, buf, 0);
	assert_s(buf, "1234");
	zsets(a, "-1234");
	zseti(b, -1234);
	zseti(c, 1234);
	assert(zcmp(a, _0), < 0);
	assert(zcmp(a, b), == 0);
	assert(zcmpmag(a, c), == 0);
	assert(zcmp(a, c), < 0);
	zstr(a, buf, 0);
	assert_s(buf, "-1234");
	assert_s(zstr(a, buf, 0), "-1234");

	zsetu(d, 100000UL);
	zrand(a, FAST_RANDOM, UNIFORM, d);
	assert(zcmp(a, _0), >= 0);
	assert(zcmp(a, d), <= 0);
	zrand(b, SECURE_RANDOM, UNIFORM, d);
	assert(zcmp(b, _0), >= 0);
	assert(zcmp(b, d), <= 0);
	zrand(c, FASTEST_RANDOM, UNIFORM, d);
	assert(zcmp(c, _0), >= 0);
	assert(zcmp(c, d), <= 0);
	assert(zcmp(a, b), != 0);
	assert(zcmp(a, c), != 0);
	assert(zcmp(b, c), != 0);

	zsetu(d, 100000UL);
	zrand(a, DEFAULT_RANDOM, QUASIUNIFORM, d);
	assert(zcmp(a, _0), >= 0);
	assert(zcmp(a, d), <= 0);
	zrand(b, DEFAULT_RANDOM, QUASIUNIFORM, d);
	assert(zcmp(b, _0), >= 0);
	assert(zcmp(b, d), <= 0);
	zrand(c, DEFAULT_RANDOM, QUASIUNIFORM, d);
	assert(zcmp(c, _0), >= 0);
	assert(zcmp(c, d), <= 0);
	assert(zcmp(a, b), != 0);
	assert(zcmp(a, c), != 0);
	assert(zcmp(b, c), != 0);

	zsetu(d, 100000UL);
	zrand(a, DEFAULT_RANDOM, MODUNIFORM, d);
	assert(zcmp(a, _0), >= 0);
	assert(zcmp(a, d), <= 0);
	zrand(b, DEFAULT_RANDOM, MODUNIFORM, d);
	assert(zcmp(b, _0), >= 0);
	assert(zcmp(b, d), <= 0);
	zrand(c, DEFAULT_RANDOM, MODUNIFORM, d);
	assert(zcmp(c, _0), >= 0);
	assert(zcmp(c, d), <= 0);
	assert(zcmp(a, b), != 0);
	assert(zcmp(a, c), != 0);
	assert(zcmp(b, c), != 0);

	assert((zseti(a, -5), zptest(0, a, 100)), == NONPRIME);
	assert((zseti(a, -4), zptest(0, a, 100)), == NONPRIME);
	assert((zseti(a, -3), zptest(0, a, 100)), == NONPRIME);
	assert((zseti(a, -2), zptest(0, a, 100)), == NONPRIME);
	assert((zseti(a, -1), zptest(0, a, 100)), == NONPRIME);
	assert((zseti(a, 0), zptest(0, a, 100)), == NONPRIME);
	assert((zseti(a, 1), zptest(0, a, 100)), == NONPRIME);
	assert((zseti(a, 2), zptest(0, a, 100)), == PRIME);
	assert((zseti(a, 3), zptest(0, a, 100)), == PRIME);
	assert((zseti(a, 4), zptest(0, a, 100)), == NONPRIME);
	assert((zseti(a, 5), zptest(0, a, 100)), != NONPRIME);
	assert((zseti(a, 6), zptest(0, a, 100)), == NONPRIME);
	assert((zseti(a, 7), zptest(0, a, 100)), != NONPRIME);
	assert((zseti(a, 8), zptest(0, a, 100)), == NONPRIME);
	assert((zseti(a, 9), zptest(0, a, 100)), == NONPRIME);
	assert((zseti(a, 10), zptest(0, a, 100)), == NONPRIME);
	assert((zseti(a, 11), zptest(0, a, 100)), != NONPRIME);
	assert((zseti(a, 101), zptest(0, a, 100)), != NONPRIME);

#if defined(ZAHL_UNSAFE)
	(void) env2;
#else
	assert_nr(zdivmod(a, b, _0, _0));
	assert_nr(zdivmod(a, b, _1, _0));
	zdivmod(a, b, _0, _1);
	zdivmod(a, b, _1, _1);
	assert_nr(zdiv(a, _0, _0));
	assert_nr(zdiv(a, _1, _0));
	zdiv(a, _0, _1);
	zdiv(a, _1, _1);
	assert_nr(zmod(a, _0, _0));
	assert_nr(zmod(a, _1, _0));
	zmod(a, _0, _1);
	zmod(a, _1, _1);
	assert_nr(zpow(a, _0, _0));
	assert_nr((zneg(_1, _1), zpow(a, _0, _1))); zneg(_1, _1);
	zpow(a, _0, _1);
	zpow(a, _1, _0);
	zneg(_1, _1), zpow(a, _1, _0), zneg(_1, _1);
	assert_nr(zmodmul(a, _1, _1, _0));
	assert_nr(zmodpow(a, _0, _0, _1));
	assert_nr((zneg(_1, _1), zmodpow(a, _0, _1, _1))); zneg(_1, _1);
	zmodpow(a, _0, _1, _1);
	zmodpow(a, _1, _0, _1);
	zneg(_1, _1), zmodpow(a, _1, _0, _1), zneg(_1, _1);
	assert_nr(zmodpow(a, _0, _0, _0));
	assert_nr((zneg(_1, _1), zmodpow(a, _0, _1, _0))); zneg(_1, _1);
	assert_nr(zmodpow(a, _0, _1, _0));
	assert_nr(zmodpow(a, _1, _0, _0));
	assert_nr((zneg(_1, _1), zmodpow(a, _1, _0, _0))); zneg(_1, _1);
	assert_nr(zpowu(a, _0, 0));
	zpowu(a, _0, 1);
	zpowu(a, _1, 0);
	zneg(_1, _1), zpowu(a, _1, 0), zneg(_1, _1);
	assert_nr(zmodpowu(a, _0, 0, _1));
	zmodpowu(a, _0, 1, _1);
	zmodpowu(a, _1, 0, _1);
	zneg(_1, _1), zmodpowu(a, _1, 0, _1), zneg(_1, _1);
	assert_nr(zmodpowu(a, _0, 0, _0));
	assert_nr((zneg(_1, _1), zmodpowu(a, _0, 1, _0))); zneg(_1, _1);
	assert_nr(zmodpowu(a, _0, 1, _0));
	assert_nr(zmodpowu(a, _1, 0, _0));
	assert_nr((zneg(_1, _1), zmodpowu(a, _1, 0, _0))); zneg(_1, _1);
	assert_nr(zstr_length(a, 0));
	assert_nr(zstr_length(a, 1));
	zstr_length(a, 2);
	zstr_length(a, 3);
#endif

	zsetu(a, 1LL);
	assert_s(zstr(a, buf, 1), "1");
	zsetu(a, 10LL);
	assert_s(zstr(a, buf, 2), "10");
	zsetu(a, 100LL);
	assert_s(zstr(a, buf, 3), "100");
	zsetu(a, 1000LL);
	assert_s(zstr(a, buf, 4), "1000");
	zsetu(a, 10000LL);
	assert_s(zstr(a, buf, BUF_N), "10000");
	zsetu(a, 100000LL);
	assert_s(zstr(a, buf, BUF_N), "100000");
	zsetu(a, 1000000LL);
	assert_s(zstr(a, buf, BUF_N), "1000000");
	zsetu(a, 10000000LL);
	assert_s(zstr(a, buf, BUF_N), "10000000");
	zsetu(a, 100000000LL);
	assert_s(zstr(a, buf, BUF_N), "100000000");
	zsetu(a, 999999999LL);
	assert_s(zstr(a, buf, BUF_N), "999999999");
	zsetu(a, 1000000000LL);
	assert_s(zstr(a, buf, BUF_N), "1000000000");
	zsetu(a, 1000000001LL);
	assert_s(zstr(a, buf, BUF_N), "1000000001");
	zsetu(a, 2000000000LL);
	assert_s(zstr(a, buf, BUF_N), "2000000000");
	zsetu(a, 2050000000LL);
	assert_s(zstr(a, buf, BUF_N), "2050000000");
	zsetu(a, 2100000000LL);
	assert_s(zstr(a, buf, BUF_N), "2100000000");
	zsetu(a, 2140000000LL);
	assert_s(zstr(a, buf, BUF_N), "2140000000");
	zsetu(a, 2147000000LL);
	assert_s(zstr(a, buf, BUF_N), "2147000000");
	zsetu(a, 2147483000LL);
	assert_s(zstr(a, buf, BUF_N), "2147483000");
	zsetu(a, 2147483640LL);
	assert_s(zstr(a, buf, BUF_N), "2147483640");
	zsetu(a, 2147483646LL);
	assert_s(zstr(a, buf, BUF_N), "2147483646");

	zseti(a, 2147483647LL);
	assert_s(zstr(a, buf, BUF_N), "2147483647");
	zseti(a, -2147483647LL);
	assert_s(zstr(a, buf, BUF_N), "-2147483647");
	zseti(a, -2147483647LL - 1LL);
	assert_s(zstr(a, buf, BUF_N), "-2147483648");

	zsetu(a, 2147483647ULL);
	assert_s(zstr(a, buf, BUF_N), "2147483647");
	zsetu(a, 2147483648ULL);
	assert_s(zstr(a, buf, BUF_N), "2147483648");
	zsetu(a, 2147483649ULL);
	assert_s(zstr(a, buf, BUF_N), "2147483649");

	zsetu(a, 3000000000ULL);
	assert_s(zstr(a, buf, BUF_N), "3000000000");
	zsetu(a, 3100000000ULL);
	assert_s(zstr(a, buf, BUF_N), "3100000000");
	zsetu(a, 3200000000ULL);
	assert_s(zstr(a, buf, BUF_N), "3200000000");
	zsetu(a, 3300000000ULL);
	assert_s(zstr(a, buf, BUF_N), "3300000000");
	zsetu(a, 3400000000ULL);
	assert_s(zstr(a, buf, BUF_N), "3400000000");
	zsetu(a, 3500000000ULL);
	assert_s(zstr(a, buf, BUF_N), "3500000000");
	zsetu(a, 3600000000ULL);
	assert_s(zstr(a, buf, BUF_N), "3600000000");
	zsetu(a, 3700000000ULL);
	assert_s(zstr(a, buf, BUF_N), "3700000000");
	zsetu(a, 3800000000ULL);
	assert_s(zstr(a, buf, BUF_N), "3800000000");
	zsetu(a, 3900000000ULL);
	assert_s(zstr(a, buf, BUF_N), "3900000000");
	zsetu(a, 3999999999ULL);
	assert_s(zstr(a, buf, BUF_N), "3999999999");
	zsetu(a, 4000000000ULL);
	assert_s(zstr(a, buf, BUF_N), "4000000000");
	zsetu(a, 4000000001ULL);
	assert_zu(zstr_length(a, 10), 10);
	assert_s(zstr(a, buf, BUF_N), "4000000001");

	zsetu(a, 4000000000ULL);
	zsetu(b, 4000000000ULL);
	zadd(c, a, a);
	zsets(d, "8000000000");
	assert(zcmp(c, d), == 0);
	zadd(c, a, b);
	assert(zcmp(c, d), == 0);
	zadd(c, c, a);
	zsets(d, "12000000000");
	assert(zcmp(c, d), == 0);
	zsub(c, c, a);
	zsets(d, "8000000000");
	assert(zcmp(c, d), == 0);
	zsub(c, c, a);
	zsets(d, "4000000000");
	assert(zcmp(c, d), == 0);
	zsets(d, "8000000000");
	zrsh(d, d, 1);
	assert(zcmp(c, d), == 0);
	zsets(a, "6234216714");
	zsets(b, "9424614147");
	zsets(d, "830476546");
	zand(c, a, b);
	assert(zcmp(c, d), == 0);
	zsets(a, "234216714");
	zsets(b, "9424614147");
	zsets(d, "9629466379");
	zor(c, a, b);
	assert(zcmp(c, d), == 0);
	zsets(a, "6234216714");
	zsets(b, "9424614147");
	zsets(d, "13997877769");
	zxor(c, a, b);
	assert(zcmp(c, d), == 0);
	zsets(a, "34216714");
	zsets(b, "9424614147");
	zsets(d, "9458821129");
	zxor(c, a, b);
	assert(zcmp(c, d), == 0);
	zsetu(a, 1000000000ULL);
	zsets(d, "1000000000000000000");
	zmul(c, a, a);
	assert(zcmp(c, d), == 0);
	zdiv(c, c, a);
	assert(zcmp(c, a), == 0);
	zsetu(a, 1000000000ULL);
	zsets(d, "1000000000000000000");
	zsqr(c, a);
	assert(zcmp(c, d), == 0);
	zsetu(a, 1000000000ULL);
	zmodpowu(c, a, 5, _3);
	assert(zcmpu(c, 1), == 0);
	zsetu(a, 1000000000ULL);
	zsets(d, "1");
	zpowu(c, a, 0);
	assert(zcmp(c, d), == 0);
	zsetu(a, 1000000000ULL);
	zsets(d, "1000000000");
	zpowu(c, a, 1);
	assert(zcmp(c, d), == 0);
	zsetu(a, 1000000000ULL);
	zsets(d, "1000000000000000000");
	zpowu(c, a, 2);
	assert(zcmp(c, d), == 0);
	zsetu(a, 1000000000ULL);
	zsets(b, "1000000000000000000");
	zsets(d, "1000000000000000000000000000");
	zmul(c, a, b);
	assert(zcmp(c, d), == 0);
	zsetu(a, 1000000000ULL);
	zsets(d, "1000000000000000000000000000");
	zmul(b, a, a);
	zmul(b, b, a);
	assert(zcmp(c, d), == 0);
	zsetu(a, 1000000000ULL);
	zsets(d, "1000000000000000000000000000");
	zpowu(c, a, 3);
	assert(zcmp(c, d), == 0);
	zsetu(a, 1000000000ULL);
	zsets(d, "1000000000000000000000000000000000000");
	zpowu(c, a, 4);
	assert(zcmp(c, d), == 0);
	zsetu(a, 1000000000ULL);
	zsets(d, "1000000000000000000000000000000000000000000000");
	zpowu(c, a, 5);
	assert(zcmp(c, d), == 0);

	zsetu(a, 4294967294ULL);
	assert_s(zstr(a, buf, BUF_N), "4294967294");
	zsetu(a, 4294967295ULL);
	assert_s(zstr(a, buf, BUF_N), "4294967295");
	zsetu(a, 4294967296ULL);
	assert_s(zstr(a, buf, BUF_N), "4294967296");
	zsetu(a, 4294967297ULL);
	assert_s(zstr(a, buf, BUF_N), "4294967297");

	zseti(a, 9223372036854775807LL);
	assert_s(zstr(a, buf, BUF_N), "9223372036854775807");
	zseti(a, -9223372036854775807LL);
	assert_s(zstr(a, buf, BUF_N), "-9223372036854775807");
	zseti(a, -9223372036854775807LL - 1LL);
	assert_s(zstr(a, buf, BUF_N), "-9223372036854775808");

	zsetu(a, 18446744073709551614ULL);
	assert_s(zstr(a, buf, BUF_N), "18446744073709551614");
	zsetu(a, 18446744073709551615ULL);
	assert_s(zstr(a, buf, BUF_N), "18446744073709551615");
	zadd(a, a, _1);
	assert_s(zstr(a, buf, BUF_N), "18446744073709551616");
	zadd(a, a, _1);
	assert_s(zstr(a, buf, BUF_N), "18446744073709551617");

	zsets(a, "1000000000000000000000000000000");
	assert_s(zstr(a, buf, BUF_N), "1000000000000000000000000000000");
	zsets(a, "+1000000000000000000000000000000");
	assert_s(zstr(a, buf, BUF_N), "1000000000000000000000000000000");
	zsets(a, "-1000000000000000000000000000000");
	assert_s(zstr(a, buf, BUF_N), "-1000000000000000000000000000000");

	zsetu(a, 1000000000000000ULL);
	zsqr(a, a);
	assert_s(zstr(a, buf, BUF_N), "1000000000000000000000000000000");

#include "test-random.c"

done:
	zfree(a), zfree(b), zfree(c), zfree(d), zfree(_0), zfree(_1), zfree(_2), zfree(_3);
	zunsetup();
	return ret;
}
示例#5
0
/* Execute actor for each item (or unit, depending on @through_units_p),
   starting from @coord, right-ward, until either:

   - end of the tree is reached
   - unformatted node is met
   - error occurred
   - @actor returns 0 or less

   Error code, or last actor return value is returned.

   This is used by plugin/dir/hashe_dir.c:reiser4_find_entry() to move through
   sequence of entries with identical keys and alikes.
*/
int reiser4_iterate_tree(reiser4_tree * tree /* tree to scan */ ,
			 coord_t *coord /* coord to start from */ ,
			 lock_handle * lh /* lock handle to start with and to
					   * update along the way */ ,
			 tree_iterate_actor_t actor /* function to call on each
						     * item/unit */ ,
			 void *arg /* argument to pass to @actor */ ,
			 znode_lock_mode mode /* lock mode on scanned nodes */ ,
			 int through_units_p /* call @actor on each item or on
					      *	each unit */ )
{
	int result;

	assert("nikita-1143", tree != NULL);
	assert("nikita-1145", coord != NULL);
	assert("nikita-1146", lh != NULL);
	assert("nikita-1147", actor != NULL);

	result = zload(coord->node);
	coord_clear_iplug(coord);
	if (result != 0)
		return result;
	if (!coord_is_existing_unit(coord)) {
		zrelse(coord->node);
		return -ENOENT;
	}
	while ((result = actor(tree, coord, lh, arg)) > 0) {
		/* move further  */
		if ((through_units_p && coord_next_unit(coord)) ||
		    (!through_units_p && coord_next_item(coord))) {
			do {
				lock_handle couple;

				/* move to the next node  */
				init_lh(&couple);
				result =
				    reiser4_get_right_neighbor(&couple,
							       coord->node,
							       (int)mode,
							       GN_CAN_USE_UPPER_LEVELS);
				zrelse(coord->node);
				if (result == 0) {

					result = zload(couple.node);
					if (result != 0) {
						done_lh(&couple);
						return result;
					}

					coord_init_first_unit(coord,
							      couple.node);
					done_lh(lh);
					move_lh(lh, &couple);
				} else
					return result;
			} while (node_is_empty(coord->node));
		}

		assert("nikita-1149", coord_is_existing_unit(coord));
	}
	zrelse(coord->node);
	return result;
}
示例#6
0
/**
 * reiser4_replace_extent - replace extent and paste 1 or 2 after it
 * @un_extent: coordinate of extent to be overwritten
 * @lh: need better comment
 * @key: need better comment
 * @exts_to_add: data prepared for insertion into tree
 * @replace: need better comment
 * @flags: need better comment
 * @return_insert_position: need better comment
 *
 * Overwrites one extent, pastes 1 or 2 more ones after overwritten one.  If
 * @return_inserted_position is 1 - @un_extent and @lh are returned set to
 * first of newly inserted units, if it is 0 - @un_extent and @lh are returned
 * set to extent which was overwritten.
 */
int reiser4_replace_extent(struct replace_handle *h,
                           int return_inserted_position)
{
    int result;
    znode *orig_znode;
    /*ON_DEBUG(reiser4_extent orig_ext);*/	/* this is for debugging */

    assert("vs-990", coord_is_existing_unit(h->coord));
    assert("vs-1375", znode_is_write_locked(h->coord->node));
    assert("vs-1426", extent_get_width(&h->overwrite) != 0);
    assert("vs-1427", extent_get_width(&h->new_extents[0]) != 0);
    assert("vs-1427", ergo(h->nr_new_extents == 2,
                           extent_get_width(&h->new_extents[1]) != 0));

    /* compose structure for paste */
    init_new_extent(&h->item, &h->new_extents[0], h->nr_new_extents);

    coord_dup(&h->coord_after, h->coord);
    init_lh(&h->lh_after);
    copy_lh(&h->lh_after, h->lh);
    reiser4_tap_init(&h->watch, &h->coord_after, &h->lh_after, ZNODE_WRITE_LOCK);
    reiser4_tap_monitor(&h->watch);

    ON_DEBUG(h->orig_ext = *extent_by_coord(h->coord));
    orig_znode = h->coord->node;

#if REISER4_DEBUG
    /* make sure that key is set properly */
    unit_key_by_coord(h->coord, &h->tmp);
    set_key_offset(&h->tmp,
                   get_key_offset(&h->tmp) +
                   extent_get_width(&h->overwrite) * current_blocksize);
    assert("vs-1080", keyeq(&h->tmp, &h->paste_key));
#endif

    /* set insert point after unit to be replaced */
    h->coord->between = AFTER_UNIT;

    result = insert_into_item(h->coord, return_inserted_position ? h->lh : NULL,
                              &h->paste_key, &h->item, h->flags);
    if (!result) {
        /* now we have to replace the unit after which new units were
           inserted. Its position is tracked by @watch */
        reiser4_extent *ext;
        znode *node;

        node = h->coord_after.node;
        if (node != orig_znode) {
            coord_clear_iplug(&h->coord_after);
            result = zload(node);
        }

        if (likely(!result)) {
            ext = extent_by_coord(&h->coord_after);

            assert("vs-987", znode_is_loaded(node));
            assert("vs-988", !memcmp(ext, &h->orig_ext, sizeof(*ext)));

            /* overwrite extent unit */
            memcpy(ext, &h->overwrite, sizeof(reiser4_extent));
            znode_make_dirty(node);

            if (node != orig_znode)
                zrelse(node);

            if (return_inserted_position == 0) {
                /* coord and lh are to be set to overwritten
                   extent */
                assert("vs-1662",
                       WITH_DATA(node, !memcmp(&h->overwrite,
                                               extent_by_coord(
                                                   &h->coord_after),
                                               sizeof(reiser4_extent))));

                *h->coord = h->coord_after;
                done_lh(h->lh);
                copy_lh(h->lh, &h->lh_after);
            } else {
                /* h->coord and h->lh are to be set to first of
                   inserted units */
                assert("vs-1663",
                       WITH_DATA(h->coord->node,
                                 !memcmp(&h->new_extents[0],
                                         extent_by_coord(h->coord),
                                         sizeof(reiser4_extent))));
                assert("vs-1664", h->lh->node == h->coord->node);
            }
        }
    }
    reiser4_tap_done(&h->watch);

    return result;
}