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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.