ocfs2_file_aio_read()

先把代码过一遍。

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 }


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