From: Al Viro <viro@ZenIV.linux.org.uk>
To: Mike Marshall <hubcap@omnibond.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>,
linux-fsdevel <linux-fsdevel@vger.kernel.org>
Subject: Re: orangefs: NAK until the ABI is documented (was Re: updated orangefs tree at kernel.org)
Date: Wed, 14 Oct 2015 00:34:10 +0100 [thread overview]
Message-ID: <20151013233410.GJ22011@ZenIV.linux.org.uk> (raw)
In-Reply-To: <CAOg9mSTwSW2DAq32T2s21YEPWHUtUunyhJDw7F+yHFxZvijUBQ@mail.gmail.com>
On Tue, Oct 13, 2015 at 01:46:54PM -0400, Mike Marshall wrote:
> > *shrug*
>
> Al, I guess what I wrote sounded pi**y, but I promise my attitude
> is 180 degrees away from that... I'm just trying to focus on what is
> most important... you've identified numerous issues, all of which
> need to be addressed, but the state of the API used by userspace
> is a show stopper: it needs documented, and then probably improved...
>
> When we have something coherent started, we'll send it your way
> so you can help make sure we're on the right track...
No problem... BTW, one note regarding the iov_iter - unlike an array of
iovec, things like "copy <that many> bytes" are easy; you don't need the
thing to start on the iovec boundary or anything like that. Simple
copy_from_iter(dest, size, iter) will take care of everything.
Something like
struct {
__u32 version;
__u32 magic;
__u64 tag;
} head;
total = iov_iter_count(iter);
if (total < 24)
short packet
n = copy_from_iter(&head, 16, iter);
if (n != 16)
failed copy
<check head.magic, find the matching upcall by head.tag>
if (not found)
stray response
/* get the beginning of response proper */
memset(op->downcall, 0, 16);
n = copy_from_iter(&op->downcall, 16, iter);
if (n < 16) {
/* it might be really short... */
if (iov_iter_count())
failed copy
/* yes, and that's too short to have a trailer */
/* just zero-pad and that's it */
memset((char *)&op->downcall + n, 0,
sizeof(op->downcall) - n);
goto done;
}
/* will there be a trailer? */
trailer_count = 0;
if (op->downcall.status == 0 && op->downcall.trailer_count) {
trailer_count = op->downcall.trailer_count;
if (total - 32 < trailer_count)
packet too short
buf = vmalloc(trailer_count)
if (!buf)
op->downcall.status = -ENOMEM;
}
n = total - 32 - trailer_count;
if (sizeof(op->downcall) - 16 < n)
packet too long
if (copy_from_iter((char *)op->downcall + 16, 0, n) != n)
failed copy
memset((char *)op->downcall + 16 + n, 0,
sizeof(op->downcall) - n - 16);
if (trailer_count) {
/* read or skip the trailer */
if (!buf) {
iov_iter_advance(trailer_count, iter);
} else {
n = copy_from_iter(buf, trailer_count, iter);
if (n < trailer_count)
failed copy
}
}
done:
...
return total;
would do marshalling and accept all cases where your current code doesn't
produce an obvious breakage. It's a lot more flexible than your current
*userland* code needs and probably more flexible than it would make sense
to have; e.g. if packets are not allowed to be just 24 bytes long, we
could turn that if (n < 16) {...} into if (n != 16) failed copy,
if we can always assume that packet is at least 16 + sizeof(op->downcall),
if could be simplified even more, etc.
There's no real benefit in using the boundary of the magic 5th segment to
tell where the trailer starts. The above is just a demo, but hopefully it
does demonstrate how to use those primitives. Basically, use copy_from_iter()
as you would use read() on stdin when writing a userland filter, with
iov_iter_advance() used to skip a given amount and iov_iter_count() telling
how much input is left.
prev parent reply other threads:[~2015-10-13 23:34 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-10-07 20:07 updated orangefs tree at kernel.org Mike Marshall
2015-10-08 21:07 ` Al Viro
2015-10-08 23:03 ` Al Viro
2015-10-09 3:41 ` Al Viro
2015-10-09 6:13 ` Al Viro
2015-10-09 19:22 ` Al Viro
2015-10-10 2:31 ` Al Viro
2015-10-10 20:23 ` Al Viro
2015-10-10 23:10 ` orangefs: NAK until the ABI is documented (was Re: updated orangefs tree at kernel.org) Al Viro
2015-10-12 16:20 ` Mike Marshall
2015-10-12 19:16 ` Al Viro
2015-10-13 17:46 ` Mike Marshall
2015-10-13 23:34 ` Al Viro [this message]
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=20151013233410.GJ22011@ZenIV.linux.org.uk \
--to=viro@zeniv.linux.org.uk \
--cc=hubcap@omnibond.com \
--cc=linux-fsdevel@vger.kernel.org \
--cc=torvalds@linux-foundation.org \
/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;
as well as URLs for NNTP newsgroup(s).