fs/splice.c
Source file repositories/reference/linux-study-clean/fs/splice.c
File Facts
- System
- Linux kernel
- Corpus path
fs/splice.c- Extension
.c- Size
- 46738 bytes
- Lines
- 1995
- Domain
- Core OS
- Bucket
- VFS And Filesystem Core
- Inferred role
- Core OS: syscall or user/kernel boundary
- Status
- core implementation candidate
Why This File Exists
Core operating-system implementation surface: boot, tasks, memory, VFS, syscall-facing interfaces, synchronization, credentials, and isolation.
- Core operating-system implementation surface: boot, tasks, memory, VFS, syscall-facing interfaces, synchronization, credentials, and isolation.
- Defines or participates in a user/kernel boundary; inspect argument validation, copy_from_user/copy_to_user, credentials, and dispatch target.
- Touches user memory; correctness depends on fault-safe copying and privilege boundary handling.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/bvec.hlinux/fs.hlinux/file.hlinux/pagemap.hlinux/splice.hlinux/memcontrol.hlinux/mm_inline.hlinux/swap.hlinux/writeback.hlinux/export.hlinux/syscalls.hlinux/uio.hlinux/fsnotify.hlinux/security.hlinux/gfp.hlinux/net.hlinux/socket.hlinux/sched/signal.hinternal.h
Detected Declarations
syscall vmsplicesyscall splicesyscall teefunction Copyrightfunction remove_mappingfunction page_cache_pipe_buf_releasefunction page_cache_pipe_buf_confirmfunction user_page_pipe_buf_try_stealfunction wakeup_pipe_readersfunction splice_to_pipefunction add_to_pipefunction splice_grow_spdfunction splice_shrink_spdfunction copy_splice_readfunction wakeup_pipe_writersfunction bytesfunction eat_empty_bufferfunction valuefunction splice_from_pipe_nextfunction splice_from_pipe_nextfunction __splice_from_pipefunction splice_from_pipefunction pagesfunction splice_to_socketfunction warn_unsupportedfunction do_splice_fromfunction do_splice_eoffunction rw_verify_areafunction vfs_splice_readfunction splice_direct_to_actorfunction direct_splice_actorfunction splice_file_range_actorfunction direct_file_splice_eoffunction do_splice_direct_actorfunction do_sendfilefunction do_splice_directfunction wait_for_spacefunction splice_file_to_pipefunction do_splicefunction __do_splicefunction iter_to_pipefunction pipe_to_userfunction vmsplice_to_userfunction vmsplice_to_pipefunction readfunction ipipe_prepfunction opipe_prepfunction splice_pipe_to_pipe
Annotated Snippet
SYSCALL_DEFINE4(vmsplice, int, fd, const struct iovec __user *, uiov,
unsigned long, nr_segs, unsigned int, flags)
{
struct iovec iovstack[UIO_FASTIOV];
struct iovec *iov = iovstack;
struct iov_iter iter;
ssize_t error;
int type;
if (unlikely(flags & ~SPLICE_F_ALL))
return -EINVAL;
CLASS(fd, f)(fd);
if (fd_empty(f))
return -EBADF;
if (fd_file(f)->f_mode & FMODE_WRITE)
type = ITER_SOURCE;
else if (fd_file(f)->f_mode & FMODE_READ)
type = ITER_DEST;
else
return -EBADF;
error = import_iovec(type, uiov, nr_segs,
ARRAY_SIZE(iovstack), &iov, &iter);
if (error < 0)
return error;
if (!iov_iter_count(&iter))
error = 0;
else if (type == ITER_SOURCE)
error = vmsplice_to_pipe(fd_file(f), &iter, flags);
else
error = vmsplice_to_user(fd_file(f), &iter, flags);
kfree(iov);
return error;
}
SYSCALL_DEFINE6(splice, int, fd_in, loff_t __user *, off_in,
int, fd_out, loff_t __user *, off_out,
size_t, len, unsigned int, flags)
{
if (unlikely(!len))
return 0;
if (unlikely(flags & ~SPLICE_F_ALL))
return -EINVAL;
CLASS(fd, in)(fd_in);
if (fd_empty(in))
return -EBADF;
CLASS(fd, out)(fd_out);
if (fd_empty(out))
return -EBADF;
return __do_splice(fd_file(in), off_in, fd_file(out), off_out,
len, flags);
}
/*
* Make sure there's data to read. Wait for input if we can, otherwise
* return an appropriate error.
*/
static int ipipe_prep(struct pipe_inode_info *pipe, unsigned int flags)
{
int ret;
/*
* Check the pipe occupancy without the inode lock first. This function
* is speculative anyways, so missing one is ok.
*/
if (!pipe_is_empty(pipe))
return 0;
ret = 0;
pipe_lock(pipe);
while (pipe_is_empty(pipe)) {
if (signal_pending(current)) {
ret = -ERESTARTSYS;
break;
}
if (!pipe->writers)
break;
if (flags & SPLICE_F_NONBLOCK) {
ret = -EAGAIN;
break;
}
pipe_wait_readable(pipe);
Annotation
- Immediate include surface: `linux/bvec.h`, `linux/fs.h`, `linux/file.h`, `linux/pagemap.h`, `linux/splice.h`, `linux/memcontrol.h`, `linux/mm_inline.h`, `linux/swap.h`.
- Detected declarations: `syscall vmsplice`, `syscall splice`, `syscall tee`, `function Copyright`, `function remove_mapping`, `function page_cache_pipe_buf_release`, `function page_cache_pipe_buf_confirm`, `function user_page_pipe_buf_try_steal`, `function wakeup_pipe_readers`, `function splice_to_pipe`.
- Atlas domain: Core OS / VFS And Filesystem Core.
- Implementation status: core implementation candidate.
- This snippet crosses the user/kernel memory boundary; validate fault handling and access checks before translating the pattern.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.