html5-img
1 / 17

System call – read/write

System call – read/write. read(fd, buf, count) Kernel 開啟 fd(file descriptor) 所指的 file object ,從 file object 的 f_pos 欄位開始讀取 count 個 bytes 的資料到 buf 中。 write(fd, buf, count). read/write source code. sys_read - fs/read_write.c.

Download Presentation

System call – read/write

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. System call – read/write • read(fd, buf, count) • Kernel開啟fd(file descriptor)所指的file object,從file object的f_pos欄位開始讀取count個bytes的資料到buf中。 • write(fd, buf, count)

  2. read/write source code

  3. sys_read - fs/read_write.c • asmlinkage ssize_t sys_read(unsigned int fd, char __user * buf, size_t count) • { • struct file *file; • ssize_t ret = -EBADF; • int fput_needed; • file = fget_light(fd, &fput_needed); • if (file) { • loff_t pos = file_pos_read(file); • ret = vfs_read(file, buf, count, &pos); • file_pos_write(file, pos); • fput_light(file, fput_needed); • } • return ret; • }

  4. struct file fastcall *fget_light(unsigned int fd, int *fput_needed) • { • struct file *file; • struct files_struct *files = current->files; • *fput_needed = 0; • if (likely((atomic_read(&files->count) == 1))) { • file = fcheck_files(files, fd); • } else { • rcu_read_lock(); • file = fcheck_files(files, fd); • if (file) { • if (atomic_inc_not_zero(&file->f_count)) • *fput_needed = 1; • else • /* Didn't get the reference, someone's freed */ • file = NULL; • } • rcu_read_unlock(); • } • return file; • } • fs/file_tables.c

  5. ssize_t vfs_read(struct file *file, char __user *buf, size_t count, loff_t *pos) • { • ssize_t ret; • if (!(file->f_mode & FMODE_READ)) • return -EBADF; • if (!file->f_op || (!file->f_op->read && !file->f_op->aio_read)) • return -EINVAL; • if (unlikely(!access_ok(VERIFY_WRITE, buf, count))) • return -EFAULT; • ret = rw_verify_area(READ, file, pos, count); • if (ret >= 0) { • count = ret; • ret = security_file_permission (file, MAY_READ); • if (!ret) { • if (file->f_op->read) • ret = file->f_op->read(file, buf, count, pos); • else • ret = do_sync_read(file, buf, count, pos); • if (ret > 0) { • fsnotify_access(file->f_path.dentry); • current->rchar += ret; • } • current->syscr++; • } • } • return ret; • } • fs/read_write.c

  6. sys_write - fs/read_write.c • asmlinkage ssize_t sys_write(unsigned int fd, const char __user * buf, size_t count) • { • struct file *file; • ssize_t ret = -EBADF; • int fput_needed; • file = fget_light(fd, &fput_needed); • if (file) { • loff_t pos = file_pos_read(file); • ret = vfs_write(file, buf, count, &pos); • file_pos_write(file, pos); • fput_light(file, fput_needed); • } • return ret; • }

  7. ssize_t vfs_write(struct file *file, const char __user *buf, size_t count, loff_t *pos) • { • ssize_t ret; • if (!(file->f_mode & FMODE_WRITE)) • return -EBADF; • if (!file->f_op || (!file->f_op->write && !file->f_op->aio_write)) • return -EINVAL; • if (unlikely(!access_ok(VERIFY_READ, buf, count))) • return -EFAULT; • ret = rw_verify_area(WRITE, file, pos, count); • if (ret >= 0) { • count = ret; • ret = security_file_permission (file, MAY_WRITE); • if (!ret) { • if (file->f_op->write) • ret = file->f_op->write(file, buf, count, pos); • else • ret = do_sync_write(file, buf, count, pos); • if (ret > 0) { • fsnotify_modify(file->f_path.dentry); • current->wchar += ret; • } • current->syscw++; • } • } • return ret; • } • fs/read_write.c

  8. Ext2 v.s. Ext3

  9. 檔案系統的一致性 • Ext2 • 當檔案系統龐大時,檢查需要花費大量時間。 • 對上線環境或高可用性伺服器不適用。 • EXt3 • 日誌(Journal) • 可避免對整個檔案系統做耗時檢查。 • 只需查看特定磁碟區域進行修正。

  10. 日誌式檔案系統 • 可解決保持中介資料(metadata)與普通資料區塊的一致性問題。 • 透過兩步驟進行高階修改: • 將要寫入的區塊副本儲存於日誌中 • 當對日誌的I/O資料傳輸完成之後,再將區塊寫入至檔案系統。 • 系統失敗復原 • 在資料交付給日誌之前:e2fsck會直接忽略 • 在資料交付給日誌之後:區塊副本有效,寫入檔案系統 • 需多次寫入磁碟所導致的系統效能損失。 • 只能保持系統呼叫層次的一致性。

  11. 日誌式檔案系統 • 三種日誌模式: • 日誌(Journal) • 將所有檔案系統與中介資料的改變都記錄下來。 • 安全性最高,但速度最慢 • 依序(Order) • 只有對中介資料的修改會紀錄,但會將中介資料與相關資料區塊群集起來,資料區塊會在中介資料之前寫入磁碟。 • 預定的Ext3日誌模式。 • 寫回(Writeback) • 只有對中介資料的修改會被記錄。 • 速度最快的模式。 • 可透過 mount 系統命令設定日誌模式

  12. 日誌區塊裝置層 • 通常儲存在名為 .journal的隱藏檔案 • 使用一通用核心層: • journaling block device (JBD) • 目前有Ext3、Ext4使用JDB。 • 基本架構: • 日誌紀錄(Log record) • 不可切割運算處理單元(Atomic operation handle) • 交易(Transaction)

  13. 日誌紀錄(Log record) • 系統即將發出之低階運算的描述。 • Journal_block_tag_t ( log record型態) • 儲存邏輯區塊編號與狀態編號 • Journal_head • 使用依序(Ordered)日誌模式時,附加到緩衝區的頭端。

  14. 不可切割運算處理單元(Atomic operation handle) • Log record的集合,每個系統呼叫都以不可切割方式處理。 • 確保整個高階運算都有實施,或任何低階運算沒有實施。 • Journal_start() • Journal_stop()

  15. 交易(Transaction) • 為了效率,會群集幾個不可切割運算處理單元成一個交易。 • 交易內的日誌紀錄須儲存於連續的區塊中。 • 停止接收新的處理單元: • 一段固定時間已過,通常是五秒。 • 日誌中無可用區塊供新的處理單元使用。 • Transaction_t • 描述交易的型態,最重要的是t_state欄位用來表示當前的交易狀態

  16. 交易(Transaction) • 完整的 • 交易中所有的log record已經實際寫入於日誌內,t_state欄位儲存的是T_FINSHED • 不完整的 • T_RUNNING • 仍在接收新的處理單元 • T_LOCKED • 不接收新的處理單元,但部分仍未完成 • T_FLUSH • 所有不可切割運算處理單元都已完成,但log records仍在寫入日誌中 • T_COMMIT • 所有log records都已寫入磁碟之內,但尚未標示成完整的狀態。

  17. 交易(Transaction) • 在任何時間可以有很多個交易在日誌中,但只能有一個是在執行中。 • 當交易完成後,JBD會驗證由log record所描述的所有緩衝區是否都已成功寫入至磁碟之內,之後才將一個完整的交易從日誌中刪除。

More Related