Loading fs/btrfs/file.c +16 −8 Original line number Original line Diff line number Diff line Loading @@ -1036,11 +1036,13 @@ int btrfs_mark_extent_written(struct btrfs_trans_handle *trans, * on error we return an unlocked page and the error value * on error we return an unlocked page and the error value * on success we return a locked page and 0 * on success we return a locked page and 0 */ */ static int prepare_uptodate_page(struct page *page, u64 pos) static int prepare_uptodate_page(struct page *page, u64 pos, bool force_uptodate) { { int ret = 0; int ret = 0; if ((pos & (PAGE_CACHE_SIZE - 1)) && !PageUptodate(page)) { if (((pos & (PAGE_CACHE_SIZE - 1)) || force_uptodate) && !PageUptodate(page)) { ret = btrfs_readpage(NULL, page); ret = btrfs_readpage(NULL, page); if (ret) if (ret) return ret; return ret; Loading @@ -1061,7 +1063,7 @@ static int prepare_uptodate_page(struct page *page, u64 pos) static noinline int prepare_pages(struct btrfs_root *root, struct file *file, static noinline int prepare_pages(struct btrfs_root *root, struct file *file, struct page **pages, size_t num_pages, struct page **pages, size_t num_pages, loff_t pos, unsigned long first_index, loff_t pos, unsigned long first_index, size_t write_bytes) size_t write_bytes, bool force_uptodate) { { struct extent_state *cached_state = NULL; struct extent_state *cached_state = NULL; int i; int i; Loading @@ -1086,10 +1088,11 @@ static noinline int prepare_pages(struct btrfs_root *root, struct file *file, } } if (i == 0) if (i == 0) err = prepare_uptodate_page(pages[i], pos); err = prepare_uptodate_page(pages[i], pos, force_uptodate); if (i == num_pages - 1) if (i == num_pages - 1) err = prepare_uptodate_page(pages[i], err = prepare_uptodate_page(pages[i], pos + write_bytes); pos + write_bytes, false); if (err) { if (err) { page_cache_release(pages[i]); page_cache_release(pages[i]); faili = i - 1; faili = i - 1; Loading Loading @@ -1158,6 +1161,7 @@ static noinline ssize_t __btrfs_buffered_write(struct file *file, size_t num_written = 0; size_t num_written = 0; int nrptrs; int nrptrs; int ret = 0; int ret = 0; bool force_page_uptodate = false; nrptrs = min((iov_iter_count(i) + PAGE_CACHE_SIZE - 1) / nrptrs = min((iov_iter_count(i) + PAGE_CACHE_SIZE - 1) / PAGE_CACHE_SIZE, PAGE_CACHE_SIZE / PAGE_CACHE_SIZE, PAGE_CACHE_SIZE / Loading Loading @@ -1200,7 +1204,8 @@ static noinline ssize_t __btrfs_buffered_write(struct file *file, * contents of pages from loop to loop * contents of pages from loop to loop */ */ ret = prepare_pages(root, file, pages, num_pages, ret = prepare_pages(root, file, pages, num_pages, pos, first_index, write_bytes); pos, first_index, write_bytes, force_page_uptodate); if (ret) { if (ret) { btrfs_delalloc_release_space(inode, btrfs_delalloc_release_space(inode, num_pages << PAGE_CACHE_SHIFT); num_pages << PAGE_CACHE_SHIFT); Loading @@ -1217,12 +1222,15 @@ static noinline ssize_t __btrfs_buffered_write(struct file *file, if (copied < write_bytes) if (copied < write_bytes) nrptrs = 1; nrptrs = 1; if (copied == 0) if (copied == 0) { force_page_uptodate = true; dirty_pages = 0; dirty_pages = 0; else } else { force_page_uptodate = false; dirty_pages = (copied + offset + dirty_pages = (copied + offset + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT; PAGE_CACHE_SHIFT; } /* /* * If we had a short copy we need to release the excess delaloc * If we had a short copy we need to release the excess delaloc Loading Loading
fs/btrfs/file.c +16 −8 Original line number Original line Diff line number Diff line Loading @@ -1036,11 +1036,13 @@ int btrfs_mark_extent_written(struct btrfs_trans_handle *trans, * on error we return an unlocked page and the error value * on error we return an unlocked page and the error value * on success we return a locked page and 0 * on success we return a locked page and 0 */ */ static int prepare_uptodate_page(struct page *page, u64 pos) static int prepare_uptodate_page(struct page *page, u64 pos, bool force_uptodate) { { int ret = 0; int ret = 0; if ((pos & (PAGE_CACHE_SIZE - 1)) && !PageUptodate(page)) { if (((pos & (PAGE_CACHE_SIZE - 1)) || force_uptodate) && !PageUptodate(page)) { ret = btrfs_readpage(NULL, page); ret = btrfs_readpage(NULL, page); if (ret) if (ret) return ret; return ret; Loading @@ -1061,7 +1063,7 @@ static int prepare_uptodate_page(struct page *page, u64 pos) static noinline int prepare_pages(struct btrfs_root *root, struct file *file, static noinline int prepare_pages(struct btrfs_root *root, struct file *file, struct page **pages, size_t num_pages, struct page **pages, size_t num_pages, loff_t pos, unsigned long first_index, loff_t pos, unsigned long first_index, size_t write_bytes) size_t write_bytes, bool force_uptodate) { { struct extent_state *cached_state = NULL; struct extent_state *cached_state = NULL; int i; int i; Loading @@ -1086,10 +1088,11 @@ static noinline int prepare_pages(struct btrfs_root *root, struct file *file, } } if (i == 0) if (i == 0) err = prepare_uptodate_page(pages[i], pos); err = prepare_uptodate_page(pages[i], pos, force_uptodate); if (i == num_pages - 1) if (i == num_pages - 1) err = prepare_uptodate_page(pages[i], err = prepare_uptodate_page(pages[i], pos + write_bytes); pos + write_bytes, false); if (err) { if (err) { page_cache_release(pages[i]); page_cache_release(pages[i]); faili = i - 1; faili = i - 1; Loading Loading @@ -1158,6 +1161,7 @@ static noinline ssize_t __btrfs_buffered_write(struct file *file, size_t num_written = 0; size_t num_written = 0; int nrptrs; int nrptrs; int ret = 0; int ret = 0; bool force_page_uptodate = false; nrptrs = min((iov_iter_count(i) + PAGE_CACHE_SIZE - 1) / nrptrs = min((iov_iter_count(i) + PAGE_CACHE_SIZE - 1) / PAGE_CACHE_SIZE, PAGE_CACHE_SIZE / PAGE_CACHE_SIZE, PAGE_CACHE_SIZE / Loading Loading @@ -1200,7 +1204,8 @@ static noinline ssize_t __btrfs_buffered_write(struct file *file, * contents of pages from loop to loop * contents of pages from loop to loop */ */ ret = prepare_pages(root, file, pages, num_pages, ret = prepare_pages(root, file, pages, num_pages, pos, first_index, write_bytes); pos, first_index, write_bytes, force_page_uptodate); if (ret) { if (ret) { btrfs_delalloc_release_space(inode, btrfs_delalloc_release_space(inode, num_pages << PAGE_CACHE_SHIFT); num_pages << PAGE_CACHE_SHIFT); Loading @@ -1217,12 +1222,15 @@ static noinline ssize_t __btrfs_buffered_write(struct file *file, if (copied < write_bytes) if (copied < write_bytes) nrptrs = 1; nrptrs = 1; if (copied == 0) if (copied == 0) { force_page_uptodate = true; dirty_pages = 0; dirty_pages = 0; else } else { force_page_uptodate = false; dirty_pages = (copied + offset + dirty_pages = (copied + offset + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT; PAGE_CACHE_SHIFT; } /* /* * If we had a short copy we need to release the excess delaloc * If we had a short copy we need to release the excess delaloc Loading