@@ -454,6 +454,7 @@ void shmem_truncate_range(struct inode *inode, loff_t lstart, loff_t lend)
mem_cgroup_uncharge_start();
for (i = 0; i < pagevec_count(&pvec); i++) {
struct page *page = pvec.pages[i];
+ struct page *head = NULL;
index = indices[i];
if (index > end)
@@ -464,12 +465,32 @@ void shmem_truncate_range(struct inode *inode, loff_t lstart, loff_t lend)
index, page);
continue;
}
-
if (!trylock_page(page))
continue;
+ if (PageCompound(page)) {
+ head = compound_head(page);
+ switch (compound_try_freeze(head, false)) {
+ case -1:
+ head = NULL;
+ break;
+ case 1:
+ unlock_page(page);
+ continue;
+ case 0:
+ if (!split_huge_page_file(head, page))
+ head = NULL;
+ break;
+ }
+ }
+ /* Truncate inode page may try to freez, so unfreez. */
if (page->mapping == mapping) {
VM_BUG_ON(PageWriteback(page));
+ if (head != NULL)
+ compound_unfreeze(head);
truncate_inode_page(mapping, page);
+ } else {
+ if (head != NULL)
+ compound_unfreeze(head);
}
unlock_page(page);
}
@@ -511,6 +532,7 @@ void shmem_truncate_range(struct inode *inode, loff_t lstart, loff_t lend)
mem_cgroup_uncharge_start();
for (i = 0; i < pagevec_count(&pvec); i++) {
struct page *page = pvec.pages[i];
+ struct page *head = NULL;
index = indices[i];
if (index > end)
@@ -523,9 +545,24 @@ void shmem_truncate_range(struct inode *inode, loff_t lstart, loff_t lend)
}
lock_page(page);
+ if (PageCompound(page)) {
+ head = compound_head(page);
+ if (compound_freeze(head)) {
+ if (!split_huge_page_file(head, page))
+ head = NULL;
+ } else {
+ head = NULL;
+ }
+ }
+ /* Truncate inode page may try to freez, so unfreez. */
if (page->mapping == mapping) {
VM_BUG_ON(PageWriteback(page));
+ if (head != NULL)
+ compound_unfreeze(head);
truncate_inode_page(mapping, page);
+ } else {
+ if (head != NULL)
+ compound_unfreeze(head);
}
unlock_page(page);
}
Writeback will be added in next patches, but after experimental support for huge pages for EXT 4. Signed-off-by: Radosław Smogura <mail@smogura.eu> --- mm/shmem.c | 39 ++++++++++++++++++++++++++++++++++++++- 1 files changed, 38 insertions(+), 1 deletions(-)