generic_file_aio_read()

mm/filemap.c:

1565 /**
1566  * generic_file_aio_read - generic filesystem read routine
1567  * @iocb:   kernel I/O control block
1568  * @iov:    io vector request
1569  * @nr_segs:    number of segments in the iovec
1570  * @pos:    current file position
1571  *
1572  * This is the "read()" routine for all filesystems
1573  * that can use the page cache directly.
1574  */
1575 ssize_t
1576 generic_file_aio_read(struct kiocb *iocb, const struct iovec *iov,
1577         unsigned long nr_segs, loff_t pos)
1578 {
// nr_segs=1
1579     struct file *filp = iocb->ki_filp;
1580     ssize_t retval;
1581     unsigned long seg = 0;
1582     size_t count;
1583     loff_t *ppos = &iocb->ki_pos;
1584 
1585     count = 0;
1586     retval = generic_segment_checks(iov, &nr_segs, &count, VERIFY_WRITE);
1587     if (retval)
1588         return retval;
1589 
1590     /* coalesce the iovecs and go direct-to-BIO for O_DIRECT */
1591     if (kiocb_is_direct(iocb)) {
1592         loff_t size;
1593         struct address_space *mapping;
1594         struct inode *inode;
1595 
1596         mapping = filp->f_mapping;
1597         inode = mapping->host;
1598         if (!count)
1599             goto out; /* skip atime */
1600         size = i_size_read(inode);
1601         if (pos < size) {
1602             retval = filemap_write_and_wait_range(mapping, pos,
1603                     pos + iov_length(iov, nr_segs) - 1);
1604             if (!retval) {
1605                 struct blk_plug plug;
1606 
1607                 blk_start_plug(&plug);
1608                 retval = mapping->a_ops->direct_IO(READ, iocb,
1609                             iov, pos, nr_segs);
1610                 blk_finish_plug(&plug);
1611             }
1612             if (retval > 0) {
1613                 *ppos = pos + retval;
1614                 count -= retval;
1615             }
1616 
1617             /*
1618              * Btrfs can have a short DIO read if we encounter
1619              * compressed extents, so if there was an error, or if
1620              * we've already read everything we wanted to, or if
1621              * there was a short read because we hit EOF, go ahead
1622              * and return.  Otherwise fallthrough to buffered io for
1623              * the rest of the read.
1624              */
1625             if (retval < 0 || !count || *ppos >= size) {
1626                 file_accessed(filp);
1627                 goto out;
1628             }
1629         }
1630     }
1631 
//直到这里是我们关心的;
//count = retval = 0
1632     count = retval;
1633     for (seg = 0; seg < nr_segs; seg++) {
//read_descriptor_t用来跟踪读的最新状况,一个封装起来通用的数据结构,能使有些代码也复用起来
1634         read_descriptor_t desc;
1635         loff_t offset = 0;
1636 
1637         /*
1638          * If we did a short DIO read we need to skip the section of the
1639          * iov that we've already read data into.
1640          */
1641         if (count) {
1642             if (count > iov[seg].iov_len) {
1643                 count -= iov[seg].iov_len;
1644                 continue;
1645             }
1646             offset = count;
1647             count = 0;
1648         }
1649 
1650         desc.written = 0;
1651         desc.arg.buf = iov[seg].iov_base + offset;
1652         desc.count = iov[seg].iov_len - offset;
1653         if (desc.count == 0)
1654             continue;
1655         desc.error = 0;
//do_generic_file_read()是主角,包括file_read_actor(),单独分析
1656         do_generic_file_read(filp, ppos, &desc, file_read_actor);
1657         retval += desc.written;
1658         if (desc.error) {
1659             retval = retval ?: desc.error;
1660             break;
1661         }
//如果这个if语句成立,应该表示读不到更多内容,就结束
1662         if (desc.count > 0)
1663             break;
1664     }
1665 out:
1666     return retval;
1667 }
1668 EXPORT_SYMBOL(generic_file_aio_read);


你可能感兴趣的:(generic_file_aio_read())