From: David Howells <dhowells@redhat.com> To: torvalds@linux-foundation.org, viro@zeniv.linux.org.uk Cc: dhowells@redhat.com, casey@schaufler-ca.com, sds@tycho.nsa.gov, nicolas.dichtel@6wind.com, raven@themaw.net, christian@brauner.io, andres@anarazel.de, jlayton@redhat.com, dray@redhat.com, kzak@redhat.com, keyrings@vger.kernel.org, linux-api@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-security-module@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 09/17] pipe: Add notification lossage handling [ver #5] Date: Wed, 18 Mar 2020 15:04:34 +0000 [thread overview] Message-ID: <158454387473.2863966.17743293093883875696.stgit@warthog.procyon.org.uk> (raw) In-Reply-To: <158454378820.2863966.10496767254293183123.stgit@warthog.procyon.org.uk> Add handling for loss of notifications by having read() insert a loss-notification message after it has read the pipe buffer that was last in the ring when the loss occurred. Lossage can come about either by running out of notification descriptors or by running out of space in the pipe ring. Signed-off-by: David Howells <dhowells@redhat.com> --- fs/pipe.c | 28 ++++++++++++++++++++++++++++ include/linux/pipe_fs_i.h | 7 +++++++ kernel/watch_queue.c | 2 ++ samples/watch_queue/watch_test.c | 3 +++ 4 files changed, 40 insertions(+) diff --git a/fs/pipe.c b/fs/pipe.c index 79cb0b5d83e1..deeab6c051a0 100644 --- a/fs/pipe.c +++ b/fs/pipe.c @@ -314,6 +314,30 @@ pipe_read(struct kiocb *iocb, struct iov_iter *to) unsigned int tail = pipe->tail; unsigned int mask = pipe->ring_size - 1; +#ifdef CONFIG_WATCH_QUEUE + if (pipe->note_loss) { + struct watch_notification n; + + if (total_len < 8) { + if (ret = 0) + ret = -ENOBUFS; + break; + } + + n.type = WATCH_TYPE_META; + n.subtype = WATCH_META_LOSS_NOTIFICATION; + n.info = watch_sizeof(n); + if (copy_to_iter(&n, sizeof(n), to) != sizeof(n)) { + if (ret = 0) + ret = -EFAULT; + break; + } + ret += sizeof(n); + total_len -= sizeof(n); + pipe->note_loss = false; + } +#endif + if (!pipe_empty(head, tail)) { struct pipe_buffer *buf = &pipe->bufs[tail & mask]; size_t chars = buf->len; @@ -355,6 +379,10 @@ pipe_read(struct kiocb *iocb, struct iov_iter *to) if (!buf->len) { pipe_buf_release(pipe, buf); spin_lock_irq(&pipe->rd_wait.lock); +#ifdef CONFIG_WATCH_QUEUE + if (buf->flags & PIPE_BUF_FLAG_LOSS) + pipe->note_loss = true; +#endif tail++; pipe->tail = tail; spin_unlock_irq(&pipe->rd_wait.lock); diff --git a/include/linux/pipe_fs_i.h b/include/linux/pipe_fs_i.h index eaff59a2f074..6626f511de6f 100644 --- a/include/linux/pipe_fs_i.h +++ b/include/linux/pipe_fs_i.h @@ -9,6 +9,9 @@ #define PIPE_BUF_FLAG_GIFT 0x04 /* page is a gift */ #define PIPE_BUF_FLAG_PACKET 0x08 /* read() as a packet */ #define PIPE_BUF_FLAG_WHOLE 0x10 /* read() must return entire buffer or error */ +#ifdef CONFIG_WATCH_QUEUE +#define PIPE_BUF_FLAG_LOSS 0x20 /* Message loss happened after this buffer */ +#endif /** * struct pipe_buffer - a linux kernel pipe buffer @@ -34,6 +37,7 @@ struct pipe_buffer { * @wr_wait: writer wait point in case of full pipe * @head: The point of buffer production * @tail: The point of buffer consumption + * @note_loss: The next read() should insert a data-lost message * @max_usage: The maximum number of slots that may be used in the ring * @ring_size: total number of buffers (should be a power of 2) * @nr_accounted: The amount this pipe accounts for in user->pipe_bufs @@ -56,6 +60,9 @@ struct pipe_inode_info { unsigned int tail; unsigned int max_usage; unsigned int ring_size; +#ifdef CONFIG_WATCH_QUEUE + bool note_loss; +#endif unsigned int nr_accounted; unsigned int readers; unsigned int writers; diff --git a/kernel/watch_queue.c b/kernel/watch_queue.c index ad64ea300f6d..9a9699c06709 100644 --- a/kernel/watch_queue.c +++ b/kernel/watch_queue.c @@ -132,6 +132,8 @@ static bool post_one_notification(struct watch_queue *wqueue, return done; lost: + buf = &pipe->bufs[(head - 1) & mask]; + buf->flags |= PIPE_BUF_FLAG_LOSS; goto out; } diff --git a/samples/watch_queue/watch_test.c b/samples/watch_queue/watch_test.c index 8628b4c5d567..46e618a897fe 100644 --- a/samples/watch_queue/watch_test.c +++ b/samples/watch_queue/watch_test.c @@ -120,6 +120,9 @@ static void consumer(int fd) (n.n.info & WATCH_INFO_ID) >> WATCH_INFO_ID__SHIFT); break; + case WATCH_META_LOSS_NOTIFICATION: + printf("-- LOSS --\n"); + break; default: printf("other meta record\n"); break;
WARNING: multiple messages have this Message-ID (diff)
From: David Howells <dhowells@redhat.com> To: torvalds@linux-foundation.org, viro@zeniv.linux.org.uk Cc: dhowells@redhat.com, casey@schaufler-ca.com, sds@tycho.nsa.gov, nicolas.dichtel@6wind.com, raven@themaw.net, christian@brauner.io, andres@anarazel.de, jlayton@redhat.com, dray@redhat.com, kzak@redhat.com, keyrings@vger.kernel.org, linux-api@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-security-module@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 09/17] pipe: Add notification lossage handling [ver #5] Date: Wed, 18 Mar 2020 15:04:34 +0000 [thread overview] Message-ID: <158454387473.2863966.17743293093883875696.stgit@warthog.procyon.org.uk> (raw) In-Reply-To: <158454378820.2863966.10496767254293183123.stgit@warthog.procyon.org.uk> Add handling for loss of notifications by having read() insert a loss-notification message after it has read the pipe buffer that was last in the ring when the loss occurred. Lossage can come about either by running out of notification descriptors or by running out of space in the pipe ring. Signed-off-by: David Howells <dhowells@redhat.com> --- fs/pipe.c | 28 ++++++++++++++++++++++++++++ include/linux/pipe_fs_i.h | 7 +++++++ kernel/watch_queue.c | 2 ++ samples/watch_queue/watch_test.c | 3 +++ 4 files changed, 40 insertions(+) diff --git a/fs/pipe.c b/fs/pipe.c index 79cb0b5d83e1..deeab6c051a0 100644 --- a/fs/pipe.c +++ b/fs/pipe.c @@ -314,6 +314,30 @@ pipe_read(struct kiocb *iocb, struct iov_iter *to) unsigned int tail = pipe->tail; unsigned int mask = pipe->ring_size - 1; +#ifdef CONFIG_WATCH_QUEUE + if (pipe->note_loss) { + struct watch_notification n; + + if (total_len < 8) { + if (ret == 0) + ret = -ENOBUFS; + break; + } + + n.type = WATCH_TYPE_META; + n.subtype = WATCH_META_LOSS_NOTIFICATION; + n.info = watch_sizeof(n); + if (copy_to_iter(&n, sizeof(n), to) != sizeof(n)) { + if (ret == 0) + ret = -EFAULT; + break; + } + ret += sizeof(n); + total_len -= sizeof(n); + pipe->note_loss = false; + } +#endif + if (!pipe_empty(head, tail)) { struct pipe_buffer *buf = &pipe->bufs[tail & mask]; size_t chars = buf->len; @@ -355,6 +379,10 @@ pipe_read(struct kiocb *iocb, struct iov_iter *to) if (!buf->len) { pipe_buf_release(pipe, buf); spin_lock_irq(&pipe->rd_wait.lock); +#ifdef CONFIG_WATCH_QUEUE + if (buf->flags & PIPE_BUF_FLAG_LOSS) + pipe->note_loss = true; +#endif tail++; pipe->tail = tail; spin_unlock_irq(&pipe->rd_wait.lock); diff --git a/include/linux/pipe_fs_i.h b/include/linux/pipe_fs_i.h index eaff59a2f074..6626f511de6f 100644 --- a/include/linux/pipe_fs_i.h +++ b/include/linux/pipe_fs_i.h @@ -9,6 +9,9 @@ #define PIPE_BUF_FLAG_GIFT 0x04 /* page is a gift */ #define PIPE_BUF_FLAG_PACKET 0x08 /* read() as a packet */ #define PIPE_BUF_FLAG_WHOLE 0x10 /* read() must return entire buffer or error */ +#ifdef CONFIG_WATCH_QUEUE +#define PIPE_BUF_FLAG_LOSS 0x20 /* Message loss happened after this buffer */ +#endif /** * struct pipe_buffer - a linux kernel pipe buffer @@ -34,6 +37,7 @@ struct pipe_buffer { * @wr_wait: writer wait point in case of full pipe * @head: The point of buffer production * @tail: The point of buffer consumption + * @note_loss: The next read() should insert a data-lost message * @max_usage: The maximum number of slots that may be used in the ring * @ring_size: total number of buffers (should be a power of 2) * @nr_accounted: The amount this pipe accounts for in user->pipe_bufs @@ -56,6 +60,9 @@ struct pipe_inode_info { unsigned int tail; unsigned int max_usage; unsigned int ring_size; +#ifdef CONFIG_WATCH_QUEUE + bool note_loss; +#endif unsigned int nr_accounted; unsigned int readers; unsigned int writers; diff --git a/kernel/watch_queue.c b/kernel/watch_queue.c index ad64ea300f6d..9a9699c06709 100644 --- a/kernel/watch_queue.c +++ b/kernel/watch_queue.c @@ -132,6 +132,8 @@ static bool post_one_notification(struct watch_queue *wqueue, return done; lost: + buf = &pipe->bufs[(head - 1) & mask]; + buf->flags |= PIPE_BUF_FLAG_LOSS; goto out; } diff --git a/samples/watch_queue/watch_test.c b/samples/watch_queue/watch_test.c index 8628b4c5d567..46e618a897fe 100644 --- a/samples/watch_queue/watch_test.c +++ b/samples/watch_queue/watch_test.c @@ -120,6 +120,9 @@ static void consumer(int fd) (n.n.info & WATCH_INFO_ID) >> WATCH_INFO_ID__SHIFT); break; + case WATCH_META_LOSS_NOTIFICATION: + printf("-- LOSS --\n"); + break; default: printf("other meta record\n"); break;
next prev parent reply other threads:[~2020-03-18 15:04 UTC|newest] Thread overview: 87+ messages / expand[flat|nested] mbox.gz Atom feed top 2020-03-18 15:03 [PATCH 00/17] pipe: Keyrings, mount and superblock notifications [ver #5] David Howells 2020-03-18 15:03 ` David Howells 2020-03-18 15:03 ` [PATCH 01/17] uapi: General notification queue definitions " David Howells 2020-03-18 15:03 ` [PATCH 02/17] security: Add hooks to rule on setting a watch " David Howells 2020-03-18 15:03 ` David Howells 2020-03-18 18:56 ` James Morris 2020-03-18 18:56 ` James Morris 2020-03-18 15:03 ` [PATCH 03/17] security: Add a hook for the point of notification insertion " David Howells 2020-03-18 15:03 ` David Howells 2020-03-18 18:57 ` James Morris 2020-03-18 18:57 ` James Morris 2020-03-18 15:03 ` [PATCH 04/17] pipe: Add O_NOTIFICATION_PIPE " David Howells 2020-03-18 15:03 ` [PATCH 05/17] pipe: Add general notification queue support " David Howells 2020-03-18 15:03 ` David Howells 2020-03-18 15:04 ` [PATCH 06/17] watch_queue: Add a key/keyring notification facility " David Howells 2020-03-18 15:04 ` David Howells 2020-03-18 19:04 ` James Morris 2020-03-18 19:04 ` James Morris 2020-03-18 15:04 ` [PATCH 07/17] Add sample notification program " David Howells 2020-03-18 15:04 ` David Howells 2020-03-18 15:04 ` [PATCH 08/17] pipe: Allow buffers to be marked read-whole-or-error for notifications " David Howells 2020-03-18 15:04 ` David Howells 2020-03-18 15:04 ` David Howells [this message] 2020-03-18 15:04 ` [PATCH 09/17] pipe: Add notification lossage handling " David Howells 2020-03-18 15:04 ` [PATCH 10/17] selinux: Implement the watch_key security hook " David Howells 2020-03-18 15:04 ` David Howells 2020-03-18 19:06 ` James Morris 2020-03-18 19:06 ` James Morris 2020-03-18 15:04 ` [PATCH 11/17] smack: Implement the watch_key and post_notification hooks " David Howells 2020-03-18 15:04 ` David Howells 2020-03-18 15:05 ` [PATCH 12/17] watch_queue: Add security hooks to rule on setting mount and sb watches " David Howells 2020-03-18 15:05 ` David Howells 2020-03-18 19:07 ` James Morris 2020-03-18 19:07 ` James Morris 2020-03-18 15:05 ` [PATCH 13/17] watch_queue: Implement mount topology and attribute change notifications " David Howells 2020-03-18 15:05 ` David Howells 2020-04-02 15:19 ` Miklos Szeredi 2020-04-02 15:19 ` Miklos Szeredi 2020-06-14 3:07 ` Ian Kent 2020-06-14 3:07 ` Ian Kent 2020-06-15 8:44 ` Miklos Szeredi 2020-06-15 8:44 ` Miklos Szeredi 2020-07-23 10:48 ` David Howells 2020-07-23 10:48 ` David Howells 2020-08-03 9:29 ` Miklos Szeredi 2020-08-03 9:29 ` Miklos Szeredi 2020-08-04 11:38 ` Ian Kent 2020-08-04 11:38 ` Ian Kent 2020-08-04 13:19 ` Miklos Szeredi 2020-08-04 13:19 ` Miklos Szeredi 2020-08-05 1:53 ` Ian Kent 2020-08-05 1:53 ` Ian Kent 2020-08-05 7:43 ` Miklos Szeredi 2020-08-05 7:43 ` Miklos Szeredi 2020-08-05 11:36 ` Ian Kent 2020-08-05 11:36 ` Ian Kent 2020-08-05 11:56 ` Miklos Szeredi 2020-08-05 11:56 ` Miklos Szeredi 2020-07-24 10:19 ` David Howells 2020-07-24 10:19 ` David Howells 2020-07-24 10:44 ` Ian Kent 2020-07-24 10:44 ` Ian Kent 2020-07-24 11:36 ` David Howells 2020-07-24 11:36 ` David Howells 2020-08-03 10:02 ` Miklos Szeredi 2020-08-03 10:02 ` Miklos Szeredi 2020-08-03 10:08 ` David Howells 2020-08-03 10:08 ` David Howells 2020-08-03 10:18 ` David Howells 2020-08-03 10:18 ` David Howells 2020-08-03 11:17 ` Miklos Szeredi 2020-08-03 11:17 ` Miklos Szeredi 2020-08-03 11:49 ` David Howells 2020-08-03 11:49 ` David Howells 2020-08-03 12:01 ` Ian Kent 2020-08-03 12:01 ` Ian Kent 2020-08-03 12:31 ` David Howells 2020-08-03 12:31 ` David Howells 2020-08-03 14:30 ` Ian Kent 2020-08-03 14:30 ` Ian Kent 2020-03-18 15:05 ` [PATCH 14/17] watch_queue: sample: Display mount tree " David Howells 2020-03-18 15:05 ` David Howells 2020-03-18 15:05 ` [PATCH 15/17] watch_queue: Introduce a non-repeating system-unique superblock ID " David Howells 2020-03-18 15:05 ` [PATCH 16/17] watch_queue: Add superblock notifications " David Howells 2020-03-18 15:05 ` David Howells 2020-03-18 15:05 ` [PATCH 17/17] watch_queue: sample: Display " David Howells 2020-03-18 15:05 ` David Howells
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=158454387473.2863966.17743293093883875696.stgit@warthog.procyon.org.uk \ --to=dhowells@redhat.com \ --cc=andres@anarazel.de \ --cc=casey@schaufler-ca.com \ --cc=christian@brauner.io \ --cc=dray@redhat.com \ --cc=jlayton@redhat.com \ --cc=keyrings@vger.kernel.org \ --cc=kzak@redhat.com \ --cc=linux-api@vger.kernel.org \ --cc=linux-fsdevel@vger.kernel.org \ --cc=linux-kernel@vger.kernel.org \ --cc=linux-security-module@vger.kernel.org \ --cc=nicolas.dichtel@6wind.com \ --cc=raven@themaw.net \ --cc=sds@tycho.nsa.gov \ --cc=torvalds@linux-foundation.org \ --cc=viro@zeniv.linux.org.uk \ /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: linkBe 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.