ext4 代码注释

    xiaoxiao2021-03-25  103

    int ext4_bio_write_page(struct ext4_io_submit *io, struct page *page, int len, struct writeback_control *wbc, bool keep_towrite) { struct inode *inode = page->mapping->host; unsigned block_start, blocksize; struct buffer_head *bh, *head; int ret = 0; int nr_submitted = 0; blocksize = 1 << inode->i_blkbits; BUG_ON(!PageLocked(page)); BUG_ON(PageWriteback(page)); if (keep_towrite) set_page_writeback_keepwrite(page); else set_page_writeback(page); ClearPageError(page); /* * Comments copied from block_write_full_page_endio: * * The page straddles i_size. It must be zeroed out on each and every * writepage invocation because it may be mmapped. "A file is mapped * in multiples of the page size. For a file that is not a multiple of * the page size, the remaining memory is zeroed when mapped, and * writes to that region are not written out to the file." */ if (len < PAGE_CACHE_SIZE) zero_user_segment(page, len, PAGE_CACHE_SIZE); /* * In the first loop we prepare and mark buffers to submit. We have to * mark all buffers in the page before submitting so that * end_page_writeback() cannot be called from ext4_bio_end_io() when IO * on the first buffer finishes and we are still working on submitting * the second buffer. */ bh = head = page_buffers(page); /* Step1 : 修改page里面的bh */ do { /* block_start是bh再整个page当中的offset */ block_start = bh_offset(bh); /* 如果offset超出要写的范围,对应的bh设置为uptodate */ if (block_start >= len) { clear_buffer_dirty(bh); set_buffer_uptodate(bh); /* 确保后续的bh也被设置为uptodate */ continue; } if (!buffer_dirty(bh) || buffer_delay(bh) || !buffer_mapped(bh) || buffer_unwritten(bh)) { /* A hole? We can safely clear the dirty bit */ if (!buffer_mapped(bh)) clear_buffer_dirty(bh); if (io->io_bio) ext4_io_submit(io); continue; } if (buffer_new(bh)) { clear_buffer_new(bh); unmap_underlying_metadata(bh->b_bdev, bh->b_blocknr); } set_buffer_async_write(bh); } while ((bh = bh->b_this_page) != head); /* Now submit buffers to write */ bh = head = page_buffers(page); /* Step 2:把bh添加到io结构里面 */ do { if (!buffer_async_write(bh)) continue; ret = io_submit_add_bh(io, inode, bh); if (ret) { /* * We only get here on ENOMEM. Not much else * we can do but mark the page as dirty, and * better luck next time. */ redirty_page_for_writepage(wbc, page); break; } nr_submitted++; clear_buffer_dirty(bh); } while ((bh = bh->b_this_page) != head); /* Error stopped previous loop? Clean up buffers... */ if (ret) { do { clear_buffer_async_write(bh); bh = bh->b_this_page; } while (bh != head); } unlock_page(page); /* Nothing submitted - we have to end page writeback */ if (!nr_submitted) end_page_writeback(page); return ret; }
    转载请注明原文地址: https://ju.6miu.com/read-17510.html

    最新回复(0)