先把代码过一遍。
2554 static ssize_t ocfs2_file_aio_read(struct kiocb *iocb,
2555 const struct iovec *iov,
2556 unsigned long nr_segs,
2557 loff_t pos)
2558 {
//nr_segs=1
2559 int ret = 0, rw_level = -1, have_alloc_sem = 0, lock_level = 0;
2560 struct file *filp = iocb->ki_filp;
2561 struct inode *inode = filp->f_path.dentry->d_inode;
2562
2563 trace_ocfs2_file_aio_read(inode, filp, filp->f_path.dentry,
2564 (unsigned long long)OCFS2_I(inode)->ip_blkno,
2565 filp->f_path.dentry->d_name.len,
2566 filp->f_path.dentry->d_name.name, nr_segs);
2567
2568
2569 if (!inode) {
2570 ret = -EINVAL;
2571 mlog_errno(ret);
2572 goto bail;
2573 }
2574
2575 ocfs2_iocb_clear_sem_locked(iocb);
2576
2577 /*
2578 * buffered reads protect themselves in ->readpage(). O_DIRECT reads
2579 * need locks to protect pending reads from racing with truncate.
2580 */
//我们只关心buffered io, 所以直接略过...
2581 if (kiocb_is_direct(iocb)) {
2582 down_read(&inode->i_alloc_sem);
2583 have_alloc_sem = 1;
2584 ocfs2_iocb_set_sem_locked(iocb);
2585
2586 ret = ocfs2_rw_lock(inode, 0);
2587 if (ret < 0) {
2588 mlog_errno(ret);
2589 goto bail;
2590 }
2591 rw_level = 0;
2592 /* communicate with ocfs2_dio_end_io */
2593 ocfs2_iocb_set_rw_locked(iocb, rw_level);
2594 }
2595
2596 /*
2597 * We're fine letting folks race truncates and extending
2598 * writes with read across the cluster, just like they can
2599 * locally. Hence no rw_lock during read.
2600 *
//难道同时不加锁地读写同一个文件是被允许的?
//本地的话,读写通过本地锁同步; 但是,如果集群锁不加限制,读写如何能够同步?
2601 * Take and drop the meta data lock to update inode fields
2602 * like i_size. This allows the checks down below
2603 * generic_file_aio_read() a chance of actually working.
2604 */
//ocfs2_inode_lock_atime()会检查mount参数有没有noatime,如果加了就申请PR锁,否则加EX锁;
//我测试了下,加noatime,写延迟减轻了很多,但是读特别差;
2605 ret = ocfs2_inode_lock_atime(inode, filp->f_vfsmnt, &lock_level);
2606 if (ret < 0) {
2607 mlog_errno(ret);
2608 goto bail;
2609 }
2610 ocfs2_inode_unlock(inode, lock_level);
2611
//generic_file_aio_read是主角,单独分析
2612 ret = generic_file_aio_read(iocb, iov, nr_segs, iocb->ki_pos);
2613 trace_generic_file_aio_read_ret(ret);
2614
2615 /* buffered aio wouldn't have proper lock coverage today */
2616 BUG_ON(ret == -EIOCBQUEUED && !kiocb_is_direct(iocb));
2617
2618 /* see ocfs2_file_aio_write */
2619 if (ret == -EIOCBQUEUED || !ocfs2_iocb_is_rw_locked(iocb)) {
2620 rw_level = -1;
2621 have_alloc_sem = 0;
2622 }
2623
2624 bail:
2625 if (have_alloc_sem) {
2626 up_read(&inode->i_alloc_sem);
2627 ocfs2_iocb_clear_sem_locked(iocb);
2628 }
2629 if (rw_level != -1)
2630 ocfs2_rw_unlock(inode, rw_level);
2631
2632 return ret;
2633 }