diff options
author | Kent Overstreet <kent.overstreet@linux.dev> | 2024-06-02 21:44:43 -0400 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@linux.dev> | 2024-06-02 21:44:43 -0400 |
commit | 82e11f49e37e839bfe8bbf95f86fdff1ea4ff5a8 (patch) | |
tree | af88471493f54c180068523dd2579016576a5285 /fs/ringbuffer.c | |
parent | e5eecf9e1a6dc51785db71a46d3e98d0448b5d61 (diff) |
ringbuffer: futexes?
Diffstat (limited to 'fs/ringbuffer.c')
-rw-r--r-- | fs/ringbuffer.c | 22 |
1 files changed, 22 insertions, 0 deletions
diff --git a/fs/ringbuffer.c b/fs/ringbuffer.c index 82e042c1c89b..8ba84fe299ae 100644 --- a/fs/ringbuffer.c +++ b/fs/ringbuffer.c @@ -6,6 +6,7 @@ #include <linux/errname.h> #include <linux/file.h> #include <linux/fs.h> +#include <linux/futex.h> #include <linux/init.h> #include <linux/mman.h> #include <linux/mount.h> @@ -266,6 +267,14 @@ struct ringbuffer *ringbuffer_alloc(u32 size) rb->ptrs->size = size; rb->ptrs->mask = size - 1; rb->ptrs->data_offset = PAGE_SIZE; + + if (!rb->rb_file) { + int ret = ringbuffer_alloc_inode(rb); + if (ret) { + ringbuffer_free(rb); + return ERR_PTR(ret); + } + } return rb; } @@ -326,6 +335,19 @@ err: return ret; } +static void ringbuffer_futex_key(struct ringbuffer *rb, int rw, + union futex_key *key) +{ + struct inode *inode = rb->rb_file->f_inode; + + key->both.offset |= FUT_OFF_INODE; /* inode-based key */ + key->shared.i_seq = get_inode_sequence_number(inode); + key->shared.pgoff = (1U << rb->order) - 1; + key->shared.offset = rw == READ + ? offsetof(struct ringbuffer_ptrs, head) + : offsetof(struct ringbuffer_ptrs, tail); +} + ssize_t ringbuffer_read_iter(struct ringbuffer *rb, struct iov_iter *iter, bool nonblocking) { u32 tail = rb->ptrs->tail, orig_tail = tail; |