[PATCH 16/18] SHM: Support for splitting on truncation
From: Radosław Smogura <hidden>
Date: 2012-02-16 21:25:49
Also in:
linux-mm
Subsystem:
memory management, the rest, tmpfs (shmem filesystem) · Maintainers:
Andrew Morton, Linus Torvalds, Hugh Dickins
Writeback will be added in next patches, but after experimental support for huge pages for EXT 4. Signed-off-by: Radosław Smogura <redacted> --- mm/shmem.c | 39 ++++++++++++++++++++++++++++++++++++++- 1 files changed, 38 insertions(+), 1 deletions(-)
diff --git a/mm/shmem.c b/mm/shmem.c
index 97e76b9..db377bf 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c@@ -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); }
--
1.7.3.4
--
To unsubscribe from this list: send the line "unsubscribe linux-ext4" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html