淺嘗輒止68-FAT32-內(nèi)核9

文件打開了,我們就來寫一寫。

write

系統(tǒng)調(diào)用write定義在kernel/fs/read_write.c,通過vfs_write調(diào)用file->f_op->write來寫入文件。

SYSCALL_DEFINE3(write, unsigned int, fd, const char __user *, buf,
        size_t, count)
{
    struct fd f = fdget_pos(fd);
    ssize_t ret = -EBADF;

    if (f.file) {
        loff_t pos = file_pos_read(f.file);
        ret = vfs_write(f.file, buf, count, &pos);
        if (ret >= 0)
            file_pos_write(f.file, pos);
        fdput_pos(f);
    }

    return ret;
}

FAT的文件操作如下,定義在kernel/fs/fat/file.c,可以看到.write=new_sync_write,即file->f_op->write=new_sync_write。
new_sync_write又調(diào)用了filp->f_op->write_iter,即generic_file_write_iter。

const struct file_operations fat_file_operations = {
    .llseek     = generic_file_llseek,
    .read       = new_sync_read,
    .write      = new_sync_write,
    .read_iter  = generic_file_read_iter,
    .write_iter = generic_file_write_iter,
    .mmap       = generic_file_mmap,
    .release    = fat_file_release,
    .unlocked_ioctl = fat_generic_ioctl,
#ifdef CONFIG_COMPAT
    .compat_ioctl   = fat_generic_compat_ioctl,
#endif
    .fsync      = fat_file_fsync,
    .splice_read    = generic_file_splice_read,
};

generic_file_write_iter定義在kernel/mm/filemap.c,進一步是__generic_file_write_iter==>generic_perform_write。

ssize_t generic_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
{
    struct file *file = iocb->ki_filp;
    struct inode *inode = file->f_mapping->host;
    ssize_t ret;

    mutex_lock(&inode->i_mutex);
    ret = __generic_file_write_iter(iocb, from);
    mutex_unlock(&inode->i_mutex);

    if (ret > 0) {
        ssize_t err;

        err = generic_write_sync(file, iocb->ki_pos - ret, ret);
        if (err < 0)
            ret = err;
    }
    return ret;
}

簡化如下,iov_iter_copy_from_user_atomic就是一個類似于memcpy的函數(shù),它把用戶buffer的內(nèi)容復(fù)制到內(nèi)存頁中。

ssize_t generic_perform_write(struct file *file,
                struct iov_iter *i, loff_t pos)
{
    //...
    copied = iov_iter_copy_from_user_atomic(page, i, offset, bytes);
    //...
}

其實到這里,一般的write流程就結(jié)束了,所謂內(nèi)存頁也只是某塊內(nèi)存,也就是write結(jié)束時,內(nèi)容并沒有寫到磁盤中。如果這時候突然斷電,磁盤里是沒有更新的。

內(nèi)存里的臟buffer什么時候刷到磁盤上的呢?

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • mean to add the formatted="false" attribute?.[ 46% 47325/...
    ProZoom閱讀 3,205評論 0 3
  • 進程 創(chuàng)建 創(chuàng)建進程用fork()函數(shù)。fork()為子進程創(chuàng)建新的地址空間并且拷貝頁表。子進程的虛擬地址空間...
    梅花怒閱讀 2,079評論 0 7
  • feisky云計算、虛擬化與Linux技術(shù)筆記posts - 1014, comments - 298, trac...
    不排版閱讀 4,354評論 0 5
  • 春風一度花輕暮 晚來雁棲渡 閑臥碧波慢云廬 醉依玉臂曳微步 漪漪偎渚 昵昵歸鷺 何處飛絲彌寂路 莫問逍遙還幾度 且...
    茗香酒影閱讀 244評論 0 1
  • 1.早起做早餐,送兒子上學。 2.到仙女山辦理避暑房相關(guān)事宜。 3.途中聽一個課件。
    胡月星閱讀 130評論 0 0

友情鏈接更多精彩內(nèi)容