static inline void *alloc_rsttbl_from_idx(struct RESTART_TABLE **tbl, u32 vbo)
{
	u32 off;
	__le32 *e;
	struct RESTART_TABLE *rt = *tbl;
	u32 bytes = bytes_per_rt(rt);
	u16 esize = le16_to_cpu(rt->size);

	/* If the entry is not the table, we will have to extend the table. */
	if (vbo >= bytes) {
		/*
		 * Extend the size by computing the number of entries between
		 * the existing size and the desired index and adding 1 to that.
		 */
		u32 bytes2idx = vbo - bytes;

		/*
		 * There should always be an integral number of entries
		 * being added. Now extend the table.
		 */
		*tbl = rt = extend_rsttbl(rt, bytes2idx / esize + 1, bytes);
		if (!rt)
			return NULL;
	}

	/* See if the entry is already allocated, and just return if it is. */
	e = Add2Ptr(rt, vbo);

	if (*e == RESTART_ENTRY_ALLOCATED_LE)
		return e;

	/*
	 * Walk through the table, looking for the entry we're
	 * interested and the previous entry.
	 */
	off = le32_to_cpu(rt->first_free);
	e = Add2Ptr(rt, off);

	if (off == vbo) {
		/* this is a match */
		rt->first_free = *e;
		goto skip_looking;
	}

	/*
	 * Need to walk through the list looking for the predecessor
	 * of our entry.
	 */
	for (;;) {
		/* Remember the entry just found */
		u32 last_off = off;
		__le32 *last_e = e;

		/* Should never run of entries. */

		/* Lookup up the next entry the list. */
		off = le32_to_cpu(*last_e);
		e = Add2Ptr(rt, off);

		/* If this is our match we are done. */
		if (off == vbo) {
			*last_e = *e;

			/*
			 * If this was the last entry, we update that
			 * table as well.
			 */
			if (le32_to_cpu(rt->last_free) == off)
				rt->last_free = cpu_to_le32(last_off);
			break;
		}
	}

skip_looking:
	/* If the list is now empty, we fix the last_free as well. */
	if (!rt->first_free)
		rt->last_free = 0;

	/* Zero this entry. */
	memset(e, 0, esize);
	*e = RESTART_ENTRY_ALLOCATED_LE;

	le16_add_cpu(&rt->total, 1);

	return e;
}
static inline void *alloc_rsttbl_from_idx(struct RESTART_TABLE **tbl, u32 vbo)
{
	u32 off;
	__le32 *e;
	struct RESTART_TABLE *rt = *tbl;
	u32 bytes = bytes_per_rt(rt);
	u16 esize = le16_to_cpu(rt->size);

	 
	if (vbo >= bytes) {
		 
		u32 bytes2idx = vbo - bytes;

		 
		*tbl = rt = extend_rsttbl(rt, bytes2idx / esize + 1, bytes);
		if (!rt)
			return NULL;
	}

	 
	e = Add2Ptr(rt, vbo);

	if (*e == RESTART_ENTRY_ALLOCATED_LE)
		return e;

	 
	off = le32_to_cpu(rt->first_free);
	e = Add2Ptr(rt, off);

	if (off == vbo) {
		 
		rt->first_free = *e;
		goto skip_looking;
	}

	 
	for (;;) {
		 
		u32 last_off = off;
		__le32 *last_e = e;

		 

		 
		off = le32_to_cpu(*last_e);
		e = Add2Ptr(rt, off);

		 
		if (off == vbo) {
			*last_e = *e;

			 
			if (le32_to_cpu(rt->last_free) == off)
				rt->last_free = cpu_to_le32(last_off);
			break;
		}
	}

skip_looking:
	 
	if (!rt->first_free)
		rt->last_free = 0;

	 
	memset(e, 0, esize);
	*e = RESTART_ENTRY_ALLOCATED_LE;

	le16_add_cpu(&rt->total, 1);

	return e;
}