mirror of
https://github.com/torvalds/linux.git
synced 2024-11-10 06:01:57 +00:00
kernel: relay: remove relay_file_splice_read dead code, doesn't work
Documentation/filesystems/relay.rst says to use
return debugfs_create_file(filename, mode, parent, buf,
&relay_file_operations);
and this is the only way relay_file_operations is used.
Thus: debugfs_create_file(&relay_file_operations)
-> __debugfs_create_file(&debugfs_full_proxy_file_operations,
&relay_file_operations)
-> dentry{inode: {i_fop: &debugfs_full_proxy_file_operations},
d_fsdata: &relay_file_operations
| DEBUGFS_FSDATA_IS_REAL_FOPS_BIT}
debugfs_full_proxy_file_operations.open is full_proxy_open, which extracts
the &relay_file_operations from the dentry, and allocates via
__full_proxy_fops_init() new fops, with trivial wrappers around release,
llseek, read, write, poll, and unlocked_ioctl, then replaces the fops on
the opened file therewith.
Naturally, all thusly-created debugfs files have .splice_read = NULL.
This was introduced in commit 49d200deaa
("debugfs: prevent access to
removed files' private data") from 2016-03-22.
AFAICT, relay_file_operations is the only struct file_operations used for
debugfs which defines a .splice_read callback. Hooking it up with
> diff --git a/fs/debugfs/file.c b/fs/debugfs/file.c
> index 5063434be0fc..952fcf5b2afa 100644
> --- a/fs/debugfs/file.c
> +++ b/fs/debugfs/file.c
> @@ -328,6 +328,11 @@ FULL_PROXY_FUNC(write, ssize_t, filp,
> loff_t *ppos),
> ARGS(filp, buf, size, ppos));
>
> +FULL_PROXY_FUNC(splice_read, long, in,
> + PROTO(struct file *in, loff_t *ppos, struct pipe_inode_info *pipe,
> + size_t len, unsigned int flags),
> + ARGS(in, ppos, pipe, len, flags));
> +
> FULL_PROXY_FUNC(unlocked_ioctl, long, filp,
> PROTO(struct file *filp, unsigned int cmd, unsigned long arg),
> ARGS(filp, cmd, arg));
> @@ -382,6 +387,8 @@ static void __full_proxy_fops_init(struct file_operations *proxy_fops,
> proxy_fops->write = full_proxy_write;
> if (real_fops->poll)
> proxy_fops->poll = full_proxy_poll;
> + if (real_fops->splice_read)
> + proxy_fops->splice_read = full_proxy_splice_read;
> if (real_fops->unlocked_ioctl)
> proxy_fops->unlocked_ioctl = full_proxy_unlocked_ioctl;
> }
shows it just doesn't work, and splicing always instantly returns empty
(subsequent reads actually return the contents).
No-one noticed it became dead code in 2016, who knows if it worked back
then. Clearly no-one cares; just delete it.
Link: https://lkml.kernel.org/r/dtexwpw6zcdx7dkx3xj5gyjp5syxmyretdcbcdtvrnukd4vvuh@tarta.nabijaczleweli.xyz
Signed-off-by: Ahelenia Ziemiańska <nabijaczleweli@nabijaczleweli.xyz>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Li kunyu <kunyu@nfschina.com>
Cc: Mike Rapoport (IBM) <rppt@kernel.org>
Cc: Rafael J. Wysocki <rafael@kernel.org>
Cc: Suren Baghdasaryan <surenb@google.com>
Cc: Zhang Zhengming <zhang.zhengming@h3c.com>
Cc: Zhao Lei <zhao_lei1@hoperun.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
This commit is contained in:
parent
50bc98323c
commit
d391615618
162
kernel/relay.c
162
kernel/relay.c
@ -1073,167 +1073,6 @@ static ssize_t relay_file_read(struct file *filp,
|
|||||||
return written;
|
return written;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void relay_consume_bytes(struct rchan_buf *rbuf, int bytes_consumed)
|
|
||||||
{
|
|
||||||
rbuf->bytes_consumed += bytes_consumed;
|
|
||||||
|
|
||||||
if (rbuf->bytes_consumed >= rbuf->chan->subbuf_size) {
|
|
||||||
relay_subbufs_consumed(rbuf->chan, rbuf->cpu, 1);
|
|
||||||
rbuf->bytes_consumed %= rbuf->chan->subbuf_size;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void relay_pipe_buf_release(struct pipe_inode_info *pipe,
|
|
||||||
struct pipe_buffer *buf)
|
|
||||||
{
|
|
||||||
struct rchan_buf *rbuf;
|
|
||||||
|
|
||||||
rbuf = (struct rchan_buf *)page_private(buf->page);
|
|
||||||
relay_consume_bytes(rbuf, buf->private);
|
|
||||||
}
|
|
||||||
|
|
||||||
static const struct pipe_buf_operations relay_pipe_buf_ops = {
|
|
||||||
.release = relay_pipe_buf_release,
|
|
||||||
.try_steal = generic_pipe_buf_try_steal,
|
|
||||||
.get = generic_pipe_buf_get,
|
|
||||||
};
|
|
||||||
|
|
||||||
static void relay_page_release(struct splice_pipe_desc *spd, unsigned int i)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* subbuf_splice_actor - splice up to one subbuf's worth of data
|
|
||||||
*/
|
|
||||||
static ssize_t subbuf_splice_actor(struct file *in,
|
|
||||||
loff_t *ppos,
|
|
||||||
struct pipe_inode_info *pipe,
|
|
||||||
size_t len,
|
|
||||||
unsigned int flags,
|
|
||||||
int *nonpad_ret)
|
|
||||||
{
|
|
||||||
unsigned int pidx, poff, total_len, subbuf_pages, nr_pages;
|
|
||||||
struct rchan_buf *rbuf = in->private_data;
|
|
||||||
unsigned int subbuf_size = rbuf->chan->subbuf_size;
|
|
||||||
uint64_t pos = (uint64_t) *ppos;
|
|
||||||
uint32_t alloc_size = (uint32_t) rbuf->chan->alloc_size;
|
|
||||||
size_t read_start = (size_t) do_div(pos, alloc_size);
|
|
||||||
size_t read_subbuf = read_start / subbuf_size;
|
|
||||||
size_t padding = rbuf->padding[read_subbuf];
|
|
||||||
size_t nonpad_end = read_subbuf * subbuf_size + subbuf_size - padding;
|
|
||||||
struct page *pages[PIPE_DEF_BUFFERS];
|
|
||||||
struct partial_page partial[PIPE_DEF_BUFFERS];
|
|
||||||
struct splice_pipe_desc spd = {
|
|
||||||
.pages = pages,
|
|
||||||
.nr_pages = 0,
|
|
||||||
.nr_pages_max = PIPE_DEF_BUFFERS,
|
|
||||||
.partial = partial,
|
|
||||||
.ops = &relay_pipe_buf_ops,
|
|
||||||
.spd_release = relay_page_release,
|
|
||||||
};
|
|
||||||
ssize_t ret;
|
|
||||||
|
|
||||||
if (rbuf->subbufs_produced == rbuf->subbufs_consumed)
|
|
||||||
return 0;
|
|
||||||
if (splice_grow_spd(pipe, &spd))
|
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Adjust read len, if longer than what is available
|
|
||||||
*/
|
|
||||||
if (len > (subbuf_size - read_start % subbuf_size))
|
|
||||||
len = subbuf_size - read_start % subbuf_size;
|
|
||||||
|
|
||||||
subbuf_pages = rbuf->chan->alloc_size >> PAGE_SHIFT;
|
|
||||||
pidx = (read_start / PAGE_SIZE) % subbuf_pages;
|
|
||||||
poff = read_start & ~PAGE_MASK;
|
|
||||||
nr_pages = min_t(unsigned int, subbuf_pages, spd.nr_pages_max);
|
|
||||||
|
|
||||||
for (total_len = 0; spd.nr_pages < nr_pages; spd.nr_pages++) {
|
|
||||||
unsigned int this_len, this_end, private;
|
|
||||||
unsigned int cur_pos = read_start + total_len;
|
|
||||||
|
|
||||||
if (!len)
|
|
||||||
break;
|
|
||||||
|
|
||||||
this_len = min_t(unsigned long, len, PAGE_SIZE - poff);
|
|
||||||
private = this_len;
|
|
||||||
|
|
||||||
spd.pages[spd.nr_pages] = rbuf->page_array[pidx];
|
|
||||||
spd.partial[spd.nr_pages].offset = poff;
|
|
||||||
|
|
||||||
this_end = cur_pos + this_len;
|
|
||||||
if (this_end >= nonpad_end) {
|
|
||||||
this_len = nonpad_end - cur_pos;
|
|
||||||
private = this_len + padding;
|
|
||||||
}
|
|
||||||
spd.partial[spd.nr_pages].len = this_len;
|
|
||||||
spd.partial[spd.nr_pages].private = private;
|
|
||||||
|
|
||||||
len -= this_len;
|
|
||||||
total_len += this_len;
|
|
||||||
poff = 0;
|
|
||||||
pidx = (pidx + 1) % subbuf_pages;
|
|
||||||
|
|
||||||
if (this_end >= nonpad_end) {
|
|
||||||
spd.nr_pages++;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = 0;
|
|
||||||
if (!spd.nr_pages)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
ret = *nonpad_ret = splice_to_pipe(pipe, &spd);
|
|
||||||
if (ret < 0 || ret < total_len)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
if (read_start + ret == nonpad_end)
|
|
||||||
ret += padding;
|
|
||||||
|
|
||||||
out:
|
|
||||||
splice_shrink_spd(&spd);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static ssize_t relay_file_splice_read(struct file *in,
|
|
||||||
loff_t *ppos,
|
|
||||||
struct pipe_inode_info *pipe,
|
|
||||||
size_t len,
|
|
||||||
unsigned int flags)
|
|
||||||
{
|
|
||||||
ssize_t spliced;
|
|
||||||
int ret;
|
|
||||||
int nonpad_ret = 0;
|
|
||||||
|
|
||||||
ret = 0;
|
|
||||||
spliced = 0;
|
|
||||||
|
|
||||||
while (len && !spliced) {
|
|
||||||
ret = subbuf_splice_actor(in, ppos, pipe, len, flags, &nonpad_ret);
|
|
||||||
if (ret < 0)
|
|
||||||
break;
|
|
||||||
else if (!ret) {
|
|
||||||
if (flags & SPLICE_F_NONBLOCK)
|
|
||||||
ret = -EAGAIN;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
*ppos += ret;
|
|
||||||
if (ret > len)
|
|
||||||
len = 0;
|
|
||||||
else
|
|
||||||
len -= ret;
|
|
||||||
spliced += nonpad_ret;
|
|
||||||
nonpad_ret = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (spliced)
|
|
||||||
return spliced;
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
const struct file_operations relay_file_operations = {
|
const struct file_operations relay_file_operations = {
|
||||||
.open = relay_file_open,
|
.open = relay_file_open,
|
||||||
@ -1242,6 +1081,5 @@ const struct file_operations relay_file_operations = {
|
|||||||
.read = relay_file_read,
|
.read = relay_file_read,
|
||||||
.llseek = no_llseek,
|
.llseek = no_llseek,
|
||||||
.release = relay_file_release,
|
.release = relay_file_release,
|
||||||
.splice_read = relay_file_splice_read,
|
|
||||||
};
|
};
|
||||||
EXPORT_SYMBOL_GPL(relay_file_operations);
|
EXPORT_SYMBOL_GPL(relay_file_operations);
|
||||||
|
Loading…
Reference in New Issue
Block a user