Unexpected behavior from xarray - Is it expected?

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Matthew Hi

First I want to thank you for the great xarray tool. I use it heavily with great joy & ease

However I have encountered a bug in my code which I did not expect, as follows:

I need code in the very hot-path that is looping on the xarray in an unusual way.
What I need is to scan a range from x-x+l but I need to break on first "hole" ie.
first entry that was not __xa_store() to. So I am using this loop:
	rcu_read_lock();

	for (xae = xas_load(&xas); xae; xae = xas_next(&xas)) {
		...
	}

Every thing works fine and I usually get a NULL from xas_next() (or xas_load())
on first hole, And the loop exits.

But in the case that I have entered a *single* xa_store() *at index 0*, but then try
to GET a range 0-Y I get these unexpected results:
	xas_next() will return the same entry repeatedly
I have put some prints (see full code below):

zuf: pi_pr [zuf_pi_get_range:248] [5] [@x0] GET bn=0x11e8 xae=0x23d1 xa_index=0x0 xa_offset=0x0
zuf: pi_pr [zuf_pi_get_range:248] [5] [@x1] GET bn=0x11e8 xae=0x23d1 xa_index=0x1 xa_offset=0x0
zuf: pi_pr [zuf_pi_get_range:248] [5] [@x2] GET bn=0x11e8 xae=0x23d1 xa_index=0x2 xa_offset=0x0
zuf: pi_pr [zuf_pi_get_range:248] [5] [@x3] GET bn=0x11e8 xae=0x23d1 xa_index=0x3 xa_offset=0x0
zuf: pi_pr [zuf_pi_get_range:248] [5] [@x4] GET bn=0x11e8 xae=0x23d1 xa_index=0x4 xa_offset=0x0
zuf: pi_pr [zuf_pi_get_range:248] [5] [@x5] GET bn=0x11e8 xae=0x23d1 xa_index=0x5 xa_offset=0x0
zuf: pi_pr [zuf_pi_get_range:248] [5] [@x6] GET bn=0x11e8 xae=0x23d1 xa_index=0x6 xa_offset=0x0

The loop only stopped because of some other condition.

[Q] Is this expected from a single xa_store() at 0?

[I am not even sure how to safely check this because consecutive entries may have
 the same exact value.

 Should I check for xa_offset not changing or should I use something else other than
 xas_next()?

 Do I must use xa_load() and take/release the rcu_lock every iteration?
]

Here is the full code.

<pi.c>
#include <linux/xarray.h>

#define xa_2_bn(xae)	xa_to_value(xae)

struct _pi_info {
	/* IN */
	ulong start;	/* start index to get	*/
	uint requested;	/* Num bns requested	*/
	/* OUT */
	ulong *bns;	/* array of block-numbers */
	uint cached;	/* Number of bns filled from page-index */
};

void zuf_pi_get_range(struct inode *inode, struct _pi_info *pi)
{
	XA_STATE(xas, &inode->i_mapping->i_pages, pi->start);
	void *xae;

	rcu_read_lock();

	for (xae = xas_load(&xas); xae; xae = xas_next(&xas)) {
		ulong  bn;

		if (xas_retry(&xas, xae)) {
			zuf_warn("See this yet e=0x%lx" _FMT_XAS "\n",
				 (ulong)xae, _PR_XAS(xas));
			continue;
		}

		bn = xa_2_bn(xae);

		zuf_dbg_pi("[%ld] [@x%lx] GET bn=0x%lx xae=0x%lx xa_index=0x%lx xa_offset=0x%x\n",
			   inode->i_ino, pi->start + pi->cached, bn, (ulong)xae, xas.xa_index, xas.xa_offset);

		pi->bns[pi->cached++] = bn;
		if (pi->cached == pi->requested)
			break; /* ALL DONE */
	}

	rcu_read_unlock();
}
<pi.c>

Thank you for looking, good day
Boaz




[Index of Archives]     [Linux Ext4 Filesystem]     [Union Filesystem]     [Filesystem Testing]     [Ceph Users]     [Ecryptfs]     [AutoFS]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux Cachefs]     [Reiser Filesystem]     [Linux RAID]     [Samba]     [Device Mapper]     [CEPH Development]

  Powered by Linux