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);