從vfs_write()到ocfs2_file_aio_write()

直接來看下ftrace打印出來的路徑:測試

 3)               |  vfs_write() {
 3)               |    do_sync_write() {
 3)   2.805 us    |      ocfs2_file_aio_write();
 3)   3.285 us    |    }
 3)   4.392 us    |  }


vfs_write()代碼邏輯很簡單,檢查參數,確認用戶態buf可用,回調具體文件系統實現的write方法,而後觸發fnotify,指針

更新進程IO記賬,包括寫字節數和自增寫系統調用數。
code

404 ssize_t vfs_write(struct file *file, const char __user *buf, size_t count, loff_t *pos)
405 {
406     ssize_t ret;
407 
408     if (!(file->f_mode & FMODE_WRITE))
409         return -EBADF;
410     if (!file->f_op || (!file->f_op->write && !file->f_op->aio_write))
411         return -EINVAL;
412     if (unlikely(!access_ok(VERIFY_READ, buf, count)))
413         return -EFAULT;
414 
415     ret = rw_verify_area(WRITE, file, pos, count);
416     if (ret >= 0) {
417         count = ret;
418         if (file->f_op->write)
419             ret = file->f_op->write(file, buf, count, pos);
420         else
421             ret = do_sync_write(file, buf, count, pos);
422         if (ret > 0) {
423             fsnotify_modify(file);
424             add_wchar(current, ret);
425         }
426         inc_syscw(current);
427     }
428 
429     return ret;
430 }

ocfs2的文件操做表,並無直接將.write和ocfs2_file_aio_write()掛鉤,fs/ocfs2/file.c:進程

2656 const struct file_operations ocfs2_fops = {
2657         .llseek         = generic_file_llseek,
2658         .read           = do_sync_read,
2659         .write          = do_sync_write,
2660         .mmap           = ocfs2_mmap,
2661         .fsync          = ocfs2_sync_file,
2662         .release        = ocfs2_file_release,
2663         .open           = ocfs2_file_open,
2664         .aio_read       = ocfs2_file_aio_read,
2665         .aio_write      = ocfs2_file_aio_write,
2666         .unlocked_ioctl = ocfs2_ioctl,
2667 #ifdef CONFIG_COMPAT
2668         .compat_ioctl   = ocfs2_compat_ioctl,
2669 #endif
2670         .lock           = ocfs2_lock,
2671         .flock          = ocfs2_flock,
2672         .splice_read    = ocfs2_file_splice_read,
2673         .splice_write   = ocfs2_file_splice_write,
2674         .fallocate      = ocfs2_fallocate,
2675 };
2676 
2677 const struct file_operations ocfs2_dops = {
2678         .llseek         = generic_file_llseek,
2679         .read           = generic_read_dir,
2680         .readdir        = ocfs2_readdir,
2681         .fsync          = ocfs2_sync_file,
2682         .release        = ocfs2_dir_release,
2683         .open           = ocfs2_dir_open,
2684         .unlocked_ioctl = ocfs2_ioctl,
2685 #ifdef CONFIG_COMPAT
2686         .compat_ioctl   = ocfs2_compat_ioctl,
2687 #endif
2688         .lock           = ocfs2_lock,
2689         .flock          = ocfs2_flock,
2690 };

do_sync_write()是vfs層的出口,也是ocfs2文件系統層的入口,具體文件系統接下來是要跟快設備打交道的,是時候甩掉vfs層的東西了,從參數上來看就是把file結構體,用戶態buf,文件指針ppos,轉換到kiocb和iovec結構體。 kiocb不少子段是從file結構體mirror的,還有字段指向進程。it

我測試了下,讀寫同一個文件狀況下wait_on_retry_sync_kiocb()和wait_on_sync_kiocb()都沒有被調用。至於,何時會被調用,還不清楚。io

fs/read_write.c:class

378 ssize_t do_sync_write(struct file *filp, const char __user *buf, size_t len, loff_t *ppos)
379 {
380     struct iovec iov = { .iov_base = (void __user *)buf, .iov_len = len };
381     struct kiocb kiocb;
382     ssize_t ret;
383 
384     init_sync_kiocb(&kiocb, filp);
385     kiocb.ki_pos = *ppos;
386     kiocb.ki_left = len;
387     kiocb.ki_nbytes = len;
388 
389     for (;;) {
390         ret = filp->f_op->aio_write(&kiocb, &iov, 1, kiocb.ki_pos);
391         if (ret != -EIOCBRETRY)
392             break;
393         wait_on_retry_sync_kiocb(&kiocb);
394     }
395 
396     if (-EIOCBQUEUED == ret)
397         ret = wait_on_sync_kiocb(&kiocb);
398     *ppos = kiocb.ki_pos;
399     return ret;
400 }
相關文章
相關標籤/搜索