fs/nfs/direct.c
Source file repositories/reference/linux-study-clean/fs/nfs/direct.c
File Facts
- System
- Linux kernel
- Corpus path
fs/nfs/direct.c- Extension
.c- Size
- 29297 bytes
- Lines
- 1105
- Domain
- Core OS
- Bucket
- VFS And Filesystem Core
- Inferred role
- Core OS: exported/initcall integration point
- Status
- integration 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.
- Exports symbols or registers init work; inspect boot/module ordering and who consumes the exported contract.
- Touches user memory; correctness depends on fault-safe copying and privilege boundary handling.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/errno.hlinux/sched.hlinux/kernel.hlinux/file.hlinux/pagemap.hlinux/kref.hlinux/slab.hlinux/task_io_accounting_ops.hlinux/module.hlinux/nfs_fs.hlinux/nfs_page.hlinux/sunrpc/clnt.hlinux/uaccess.hlinux/atomic.hdelegation.hinternal.hiostat.hpnfs.hfscache.hnfstrace.h
Detected Declarations
function get_dreqfunction put_dreqfunction nfs_direct_handle_truncatedfunction nfs_direct_count_bytesfunction nfs_direct_truncate_requestfunction nfs_direct_file_adjust_size_lockedfunction nfs_swap_rwfunction nfs_direct_release_pagesfunction nfs_init_cinfo_from_dreqfunction nfs_direct_req_freefunction nfs_direct_req_releasefunction nfs_dreq_bytes_leftfunction nfs_direct_waitfunction nfs_direct_completefunction nfs_direct_read_completionfunction nfs_read_sync_pgio_errorfunction nfs_direct_pgio_initfunction nfs_direct_read_resultfunction generic_file_aio_readfunction nfs_direct_add_page_headfunction nfs_direct_join_groupfunction list_for_each_entryfunction nfs_join_page_groupfunction nfs_direct_write_scan_commit_listfunction nfs_direct_write_reschedulefunction nfs_direct_commit_completefunction nfs_direct_resched_writefunction nfs_direct_commit_schedulefunction nfs_direct_write_clear_reqsfunction nfs_direct_write_schedule_workfunction nfs_direct_write_completefunction nfs_direct_write_completionfunction nfs_write_sync_pgio_errorfunction nfs_direct_write_reschedule_iofunction nfs_direct_write_resultfunction generic_file_aio_writefunction nfs_init_directcachefunction nfs_destroy_directcacheexport nfs_dreq_bytes_left
Annotated Snippet
if (dreq->count != 0) {
res = (long) dreq->count;
WARN_ON_ONCE(dreq->count < 0);
}
dreq->iocb->ki_complete(dreq->iocb, res);
}
complete(&dreq->completion);
nfs_direct_req_release(dreq);
}
static void nfs_direct_read_completion(struct nfs_pgio_header *hdr)
{
unsigned long bytes = 0;
struct nfs_direct_req *dreq = hdr->dreq;
spin_lock(&dreq->lock);
if (test_bit(NFS_IOHDR_REDO, &hdr->flags)) {
spin_unlock(&dreq->lock);
goto out_put;
}
nfs_direct_count_bytes(dreq, hdr);
spin_unlock(&dreq->lock);
nfs_update_delegated_atime(dreq->inode);
while (!list_empty(&hdr->pages)) {
struct nfs_page *req = nfs_list_entry(hdr->pages.next);
struct page *page = req->wb_page;
if (!PageCompound(page) && bytes < hdr->good_bytes &&
(dreq->flags == NFS_ODIRECT_SHOULD_DIRTY))
set_page_dirty(page);
bytes += req->wb_bytes;
nfs_list_remove_request(req);
nfs_release_request(req);
}
out_put:
if (put_dreq(dreq))
nfs_direct_complete(dreq);
hdr->release(hdr);
}
static void nfs_read_sync_pgio_error(struct list_head *head, int error)
{
struct nfs_page *req;
while (!list_empty(head)) {
req = nfs_list_entry(head->next);
nfs_list_remove_request(req);
nfs_release_request(req);
}
}
static void nfs_direct_pgio_init(struct nfs_pgio_header *hdr)
{
get_dreq(hdr->dreq);
set_bit(NFS_IOHDR_ODIRECT, &hdr->flags);
}
static const struct nfs_pgio_completion_ops nfs_direct_read_completion_ops = {
.error_cleanup = nfs_read_sync_pgio_error,
.init_hdr = nfs_direct_pgio_init,
.completion = nfs_direct_read_completion,
};
/*
* For each rsize'd chunk of the user's buffer, dispatch an NFS READ
* operation. If nfs_readdata_alloc() or get_user_pages() fails,
* bail and stop sending more reads. Read length accounting is
* handled automatically by nfs_direct_read_result(). Otherwise, if
* no requests have been sent, just return an error.
*/
static ssize_t nfs_direct_read_schedule_iovec(struct nfs_direct_req *dreq,
struct iov_iter *iter,
loff_t pos)
{
struct nfs_pageio_descriptor desc;
struct inode *inode = dreq->inode;
ssize_t result = -EINVAL;
size_t requested_bytes = 0;
size_t rsize = max_t(size_t, NFS_SERVER(inode)->rsize, PAGE_SIZE);
nfs_pageio_init_read(&desc, dreq->inode, false,
&nfs_direct_read_completion_ops);
get_dreq(dreq);
desc.pg_dreq = dreq;
Annotation
- Immediate include surface: `linux/errno.h`, `linux/sched.h`, `linux/kernel.h`, `linux/file.h`, `linux/pagemap.h`, `linux/kref.h`, `linux/slab.h`, `linux/task_io_accounting_ops.h`.
- Detected declarations: `function get_dreq`, `function put_dreq`, `function nfs_direct_handle_truncated`, `function nfs_direct_count_bytes`, `function nfs_direct_truncate_request`, `function nfs_direct_file_adjust_size_locked`, `function nfs_swap_rw`, `function nfs_direct_release_pages`, `function nfs_init_cinfo_from_dreq`, `function nfs_direct_req_free`.
- Atlas domain: Core OS / VFS And Filesystem Core.
- Implementation status: integration implementation candidate.
- This snippet crosses the user/kernel memory boundary; validate fault handling and access checks before translating the pattern.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
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.