From: Dave Chinner <david@fromorbit.com>
To: Mark Tinguely <tinguely@sgi.com>
Cc: xfs@oss.sgi.com
Subject: Re: [PATCH v2] xfs_db: fix the setting of unaligned directory fields
Date: Wed, 12 Feb 2014 11:22:22 +1100 [thread overview]
Message-ID: <20140212002222.GO13647@dastard> (raw)
In-Reply-To: <52FA3141.20901@sgi.com>
On Tue, Feb 11, 2014 at 08:18:41AM -0600, Mark Tinguely wrote:
> On 02/10/14 19:31, Dave Chinner wrote:
> >On Mon, Feb 10, 2014 at 05:09:12PM -0600, Mark Tinguely wrote:
>
> <delete>
>
> >>> + * Values larger than 64 bits are array of hex digits that
> >>> + * already in the desired ordering (example UUID).
> >>> */
> >>> - *value = strtoll(arg, NULL, 0);
> >>> + if (bit_length > 64)
> >>> + return buf;
> >I don't understand why you added this - how can we have input left
> >that we need to parse after the above loop? @bytes will always be<=
> >0 at this point in time, which means we have no space in the bit
> >field left to put values into....
>
> The comment explains the return.
If the comment answered my question then I wouldn't have asked it.
> If the input bit_length is bigger than 64 bit then it is an array of
> hex numbers (for example UUID can be entered this way).
Yes, I know that.
> buf is the beginning of the allocated array before rbuf pointer put
> nibbles into it. So this returns the beginning of the hex bytes.
Yes, I know that, too.
> If this return is not taken then it is 64 bits or less and is some
> kind of integer. The integer will get its fields fixed and converted
> to big endian....
Oh, now I understand what you've done - you've changed the
definition of what a hex block contains. A hex block is a
hex-encoded binary format - it is just an array of bytes. What
you've changed is that you now define a hex block of less than 64
bits to encode a host-endian format integer.
That's what you comment didn't explain and what confused me - why we
should be bit shifting or endian converting a raw data encoding.
For example, if I want to write 4 bytes of hex data to a field, then
I use "#12345678" to do it. When I dump the raw contents of that
field, I expect to see four bytes in big endian format in that
field: 12 34 56 78. When I print the structure value, I expect to
see the host-endian conversion of that raw data, not the on-disk
encoded value.
IOWs, we do not want small hex block arrays to be interpretted as a
host endian integer - if you need to enter an integer value in host
endian then use "0x12345678". i.e. hex blocks are not integers. i.e.
xfs_db> write lsn #12345678
lsn = 0x78563412
xfs_db> write lsn 0x12345678
lsn = 0x12345678
The above behaviour is correct and expected on a little endian host.
Having them both result in "lsn = 0x12345678" is not the correct or
desired behaviour. I didn't pick this up when looking that the tst
you wrote, but it's now obvious:
+$XFS_DB_PROG -x -c "inode $FILE_INO" -c "write core.gen #185a" $SCRATCH_DEV
+$XFS_DB_PROG -x -c "inode $FILE_INO" -c "write core.gen #a518" $SCRATCH_DEV
...
+core.gen = 6234
+core.gen = 42264
This is how a little endian host should behave:
xfs_db> write core.gen 0xa518
core.gen = 42264
xfs_db> write core.gen #a518
core.gen = 6309
xfs_db> write core.gen 0x18a5
core.gen = 6309
xfs_db> write core.gen #18a5
core.gen = 42264
So, back to my original question, now I undersand what you've done,
which was "how does hexblock data on unaligned bit_length fields
work?". The code ends up like this:
int bytes = bit_length / NBBY;
while (*arg && bytes--) {
.....
}
if (bytes < 0 && *arg)
return NULL;
/*
* Values larger than 64 bits are array of hex digits that
* already in the desired ordering (example UUID).
*/
if (bit_length > 64)
return buf;
} else {
....
}
/* do integer parsing */
......
Let's say bit length is 1 (e.g. unwritten extent flag) and we pass a
value of "#1". That gives us bytes = 0 as the initial condition.
This:
while (*arg && bytes--)
sees *arg != NULL and bytes = 0 so it doesn't run the loop and
then post-decrements bytes Now we have bytes = -1 and *arg != 0.
So we return NULL instead of parsing the byte.
The same thing will happen with any unaligned bit field that needs
the high byte set via this code as it will fail to parse the last
character of the input.
IOWs, using hexblock format on unaligned bitfields does not work
properly. In fact, it's never been supported, as hex blocks
were never intended to be used that way. i.e. the use for a hexblock
when writting an extent record to to write the entire record as a
binary value, not to write individual elements as integer values....
Hence I'd suggest that "if (bit_field & NBBY) return NULL;" is
appropriate for hex block format input, and the input should never
be treated as a host-endian integer...
Cheers,
Dave.
--
Dave Chinner
david@fromorbit.com
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
next prev parent reply other threads:[~2014-02-12 0:22 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-02-10 23:09 [PATCH v2] xfs_db: fix the setting of unaligned directory fields Mark Tinguely
2014-02-11 1:31 ` Dave Chinner
2014-02-11 14:18 ` Mark Tinguely
2014-02-12 0:22 ` Dave Chinner [this message]
2014-02-12 21:37 ` Mark Tinguely
2014-02-13 20:25 ` [PATCH v3] " Mark Tinguely
2014-02-18 10:34 ` Dave Chinner
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20140212002222.GO13647@dastard \
--to=david@fromorbit.com \
--cc=tinguely@sgi.com \
--cc=xfs@oss.sgi.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox