~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/fs/netfs/direct_read.c

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 // SPDX-License-Identifier: GPL-2.0-or-later
  2 /* Direct I/O support.
  3  *
  4  * Copyright (C) 2023 Red Hat, Inc. All Rights Reserved.
  5  * Written by David Howells (dhowells@redhat.com)
  6  */
  7 
  8 #include <linux/export.h>
  9 #include <linux/fs.h>
 10 #include <linux/mm.h>
 11 #include <linux/pagemap.h>
 12 #include <linux/slab.h>
 13 #include <linux/uio.h>
 14 #include <linux/sched/mm.h>
 15 #include <linux/task_io_accounting_ops.h>
 16 #include <linux/netfs.h>
 17 #include "internal.h"
 18 
 19 /**
 20  * netfs_unbuffered_read_iter_locked - Perform an unbuffered or direct I/O read
 21  * @iocb: The I/O control descriptor describing the read
 22  * @iter: The output buffer (also specifies read length)
 23  *
 24  * Perform an unbuffered I/O or direct I/O from the file in @iocb to the
 25  * output buffer.  No use is made of the pagecache.
 26  *
 27  * The caller must hold any appropriate locks.
 28  */
 29 ssize_t netfs_unbuffered_read_iter_locked(struct kiocb *iocb, struct iov_iter *iter)
 30 {
 31         struct netfs_io_request *rreq;
 32         ssize_t ret;
 33         size_t orig_count = iov_iter_count(iter);
 34         bool async = !is_sync_kiocb(iocb);
 35 
 36         _enter("");
 37 
 38         if (!orig_count)
 39                 return 0; /* Don't update atime */
 40 
 41         ret = kiocb_write_and_wait(iocb, orig_count);
 42         if (ret < 0)
 43                 return ret;
 44         file_accessed(iocb->ki_filp);
 45 
 46         rreq = netfs_alloc_request(iocb->ki_filp->f_mapping, iocb->ki_filp,
 47                                    iocb->ki_pos, orig_count,
 48                                    NETFS_DIO_READ);
 49         if (IS_ERR(rreq))
 50                 return PTR_ERR(rreq);
 51 
 52         netfs_stat(&netfs_n_rh_dio_read);
 53         trace_netfs_read(rreq, rreq->start, rreq->len, netfs_read_trace_dio_read);
 54 
 55         /* If this is an async op, we have to keep track of the destination
 56          * buffer for ourselves as the caller's iterator will be trashed when
 57          * we return.
 58          *
 59          * In such a case, extract an iterator to represent as much of the the
 60          * output buffer as we can manage.  Note that the extraction might not
 61          * be able to allocate a sufficiently large bvec array and may shorten
 62          * the request.
 63          */
 64         if (user_backed_iter(iter)) {
 65                 ret = netfs_extract_user_iter(iter, rreq->len, &rreq->iter, 0);
 66                 if (ret < 0)
 67                         goto out;
 68                 rreq->direct_bv = (struct bio_vec *)rreq->iter.bvec;
 69                 rreq->direct_bv_count = ret;
 70                 rreq->direct_bv_unpin = iov_iter_extract_will_pin(iter);
 71                 rreq->len = iov_iter_count(&rreq->iter);
 72         } else {
 73                 rreq->iter = *iter;
 74                 rreq->len = orig_count;
 75                 rreq->direct_bv_unpin = false;
 76                 iov_iter_advance(iter, orig_count);
 77         }
 78 
 79         // TODO: Set up bounce buffer if needed
 80 
 81         if (async)
 82                 rreq->iocb = iocb;
 83 
 84         ret = netfs_begin_read(rreq, is_sync_kiocb(iocb));
 85         if (ret < 0)
 86                 goto out; /* May be -EIOCBQUEUED */
 87         if (!async) {
 88                 // TODO: Copy from bounce buffer
 89                 iocb->ki_pos += rreq->transferred;
 90                 ret = rreq->transferred;
 91         }
 92 
 93 out:
 94         netfs_put_request(rreq, false, netfs_rreq_trace_put_return);
 95         if (ret > 0)
 96                 orig_count -= ret;
 97         if (ret != -EIOCBQUEUED)
 98                 iov_iter_revert(iter, orig_count - iov_iter_count(iter));
 99         return ret;
100 }
101 EXPORT_SYMBOL(netfs_unbuffered_read_iter_locked);
102 
103 /**
104  * netfs_unbuffered_read_iter - Perform an unbuffered or direct I/O read
105  * @iocb: The I/O control descriptor describing the read
106  * @iter: The output buffer (also specifies read length)
107  *
108  * Perform an unbuffered I/O or direct I/O from the file in @iocb to the
109  * output buffer.  No use is made of the pagecache.
110  */
111 ssize_t netfs_unbuffered_read_iter(struct kiocb *iocb, struct iov_iter *iter)
112 {
113         struct inode *inode = file_inode(iocb->ki_filp);
114         ssize_t ret;
115 
116         if (!iter->count)
117                 return 0; /* Don't update atime */
118 
119         ret = netfs_start_io_direct(inode);
120         if (ret == 0) {
121                 ret = netfs_unbuffered_read_iter_locked(iocb, iter);
122                 netfs_end_io_direct(inode);
123         }
124         return ret;
125 }
126 EXPORT_SYMBOL(netfs_unbuffered_read_iter);
127 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php