Loading fs/btrfs/extent_io.c +42 −6 Original line number Diff line number Diff line Loading @@ -1554,6 +1554,11 @@ static noinline u64 find_delalloc_range(struct extent_io_tree *tree, return found; } static int __process_pages_contig(struct address_space *mapping, struct page *locked_page, pgoff_t start_index, pgoff_t end_index, unsigned long page_ops, pgoff_t *index_ret); static noinline void __unlock_for_delalloc(struct inode *inode, struct page *locked_page, u64 start, u64 end) Loading Loading @@ -1731,17 +1736,24 @@ STATIC u64 find_lock_delalloc_range(struct inode *inode, return found; } static void __process_pages_contig(struct address_space *mapping, static int __process_pages_contig(struct address_space *mapping, struct page *locked_page, pgoff_t start_index, pgoff_t end_index, unsigned long page_ops) unsigned long page_ops, pgoff_t *index_ret) { unsigned long nr_pages = end_index - start_index + 1; unsigned long pages_locked = 0; pgoff_t index = start_index; struct page *pages[16]; unsigned ret; int err = 0; int i; if (page_ops & PAGE_LOCK) { ASSERT(page_ops == PAGE_LOCK); ASSERT(index_ret && *index_ret == start_index); } if ((page_ops & PAGE_SET_ERROR) && nr_pages > 0) mapping_set_error(mapping, -EIO); Loading @@ -1749,13 +1761,22 @@ static void __process_pages_contig(struct address_space *mapping, ret = find_get_pages_contig(mapping, index, min_t(unsigned long, nr_pages, ARRAY_SIZE(pages)), pages); for (i = 0; i < ret; i++) { if (ret == 0) { /* * Only if we're going to lock these pages, * can we find nothing at @index. */ ASSERT(page_ops & PAGE_LOCK); return ret; } for (i = 0; i < ret; i++) { if (page_ops & PAGE_SET_PRIVATE2) SetPagePrivate2(pages[i]); if (pages[i] == locked_page) { put_page(pages[i]); pages_locked++; continue; } if (page_ops & PAGE_CLEAR_DIRTY) Loading @@ -1768,12 +1789,27 @@ static void __process_pages_contig(struct address_space *mapping, end_page_writeback(pages[i]); if (page_ops & PAGE_UNLOCK) unlock_page(pages[i]); if (page_ops & PAGE_LOCK) { lock_page(pages[i]); if (!PageDirty(pages[i]) || pages[i]->mapping != mapping) { unlock_page(pages[i]); put_page(pages[i]); err = -EAGAIN; goto out; } } put_page(pages[i]); pages_locked++; } nr_pages -= ret; index += ret; cond_resched(); } out: if (err && index_ret) *index_ret = start_index + pages_locked - 1; return err; } void extent_clear_unlock_delalloc(struct inode *inode, u64 start, u64 end, Loading @@ -1786,7 +1822,7 @@ void extent_clear_unlock_delalloc(struct inode *inode, u64 start, u64 end, __process_pages_contig(inode->i_mapping, locked_page, start >> PAGE_SHIFT, end >> PAGE_SHIFT, page_ops); page_ops, NULL); } /* Loading fs/btrfs/extent_io.h +2 −1 Original line number Diff line number Diff line Loading @@ -45,13 +45,14 @@ #define EXTENT_BUFFER_IN_TREE 10 #define EXTENT_BUFFER_WRITE_ERR 11 /* write IO error */ /* these are flags for extent_clear_unlock_delalloc */ /* these are flags for __process_pages_contig */ #define PAGE_UNLOCK (1 << 0) #define PAGE_CLEAR_DIRTY (1 << 1) #define PAGE_SET_WRITEBACK (1 << 2) #define PAGE_END_WRITEBACK (1 << 3) #define PAGE_SET_PRIVATE2 (1 << 4) #define PAGE_SET_ERROR (1 << 5) #define PAGE_LOCK (1 << 6) /* * page->private values. Every page that is controlled by the extent Loading Loading
fs/btrfs/extent_io.c +42 −6 Original line number Diff line number Diff line Loading @@ -1554,6 +1554,11 @@ static noinline u64 find_delalloc_range(struct extent_io_tree *tree, return found; } static int __process_pages_contig(struct address_space *mapping, struct page *locked_page, pgoff_t start_index, pgoff_t end_index, unsigned long page_ops, pgoff_t *index_ret); static noinline void __unlock_for_delalloc(struct inode *inode, struct page *locked_page, u64 start, u64 end) Loading Loading @@ -1731,17 +1736,24 @@ STATIC u64 find_lock_delalloc_range(struct inode *inode, return found; } static void __process_pages_contig(struct address_space *mapping, static int __process_pages_contig(struct address_space *mapping, struct page *locked_page, pgoff_t start_index, pgoff_t end_index, unsigned long page_ops) unsigned long page_ops, pgoff_t *index_ret) { unsigned long nr_pages = end_index - start_index + 1; unsigned long pages_locked = 0; pgoff_t index = start_index; struct page *pages[16]; unsigned ret; int err = 0; int i; if (page_ops & PAGE_LOCK) { ASSERT(page_ops == PAGE_LOCK); ASSERT(index_ret && *index_ret == start_index); } if ((page_ops & PAGE_SET_ERROR) && nr_pages > 0) mapping_set_error(mapping, -EIO); Loading @@ -1749,13 +1761,22 @@ static void __process_pages_contig(struct address_space *mapping, ret = find_get_pages_contig(mapping, index, min_t(unsigned long, nr_pages, ARRAY_SIZE(pages)), pages); for (i = 0; i < ret; i++) { if (ret == 0) { /* * Only if we're going to lock these pages, * can we find nothing at @index. */ ASSERT(page_ops & PAGE_LOCK); return ret; } for (i = 0; i < ret; i++) { if (page_ops & PAGE_SET_PRIVATE2) SetPagePrivate2(pages[i]); if (pages[i] == locked_page) { put_page(pages[i]); pages_locked++; continue; } if (page_ops & PAGE_CLEAR_DIRTY) Loading @@ -1768,12 +1789,27 @@ static void __process_pages_contig(struct address_space *mapping, end_page_writeback(pages[i]); if (page_ops & PAGE_UNLOCK) unlock_page(pages[i]); if (page_ops & PAGE_LOCK) { lock_page(pages[i]); if (!PageDirty(pages[i]) || pages[i]->mapping != mapping) { unlock_page(pages[i]); put_page(pages[i]); err = -EAGAIN; goto out; } } put_page(pages[i]); pages_locked++; } nr_pages -= ret; index += ret; cond_resched(); } out: if (err && index_ret) *index_ret = start_index + pages_locked - 1; return err; } void extent_clear_unlock_delalloc(struct inode *inode, u64 start, u64 end, Loading @@ -1786,7 +1822,7 @@ void extent_clear_unlock_delalloc(struct inode *inode, u64 start, u64 end, __process_pages_contig(inode->i_mapping, locked_page, start >> PAGE_SHIFT, end >> PAGE_SHIFT, page_ops); page_ops, NULL); } /* Loading
fs/btrfs/extent_io.h +2 −1 Original line number Diff line number Diff line Loading @@ -45,13 +45,14 @@ #define EXTENT_BUFFER_IN_TREE 10 #define EXTENT_BUFFER_WRITE_ERR 11 /* write IO error */ /* these are flags for extent_clear_unlock_delalloc */ /* these are flags for __process_pages_contig */ #define PAGE_UNLOCK (1 << 0) #define PAGE_CLEAR_DIRTY (1 << 1) #define PAGE_SET_WRITEBACK (1 << 2) #define PAGE_END_WRITEBACK (1 << 3) #define PAGE_SET_PRIVATE2 (1 << 4) #define PAGE_SET_ERROR (1 << 5) #define PAGE_LOCK (1 << 6) /* * page->private values. Every page that is controlled by the extent Loading