aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndi Kleen <andi@firstfloor.org>2009-09-16 05:50:13 -0400
committerAndi Kleen <ak@linux.intel.com>2009-09-16 05:50:13 -0400
commit257187362123f15d9d1e09918cf87cebbea4e786 (patch)
tree92b768ad3f2afeda13a2acadc6d5766090ebcc60
parent83f786680aec8d030184f7ced1a0a3dd8ac81764 (diff)
HWPOISON: Define a new error_remove_page address space op for async truncation
Truncating metadata pages is not safe right now before we haven't audited all file systems. To enable truncation only for data address space define a new address_space callback error_remove_page. This is used for memory_failure.c memory error handling. This can be then set to truncate_inode_page() This patch just defines the new operation and adds documentation. Callers and users come in followon patches. Signed-off-by: Andi Kleen <ak@linux.intel.com>
-rw-r--r--Documentation/filesystems/vfs.txt7
-rw-r--r--include/linux/fs.h1
-rw-r--r--include/linux/mm.h1
-rw-r--r--mm/truncate.c17
4 files changed, 26 insertions, 0 deletions
diff --git a/Documentation/filesystems/vfs.txt b/Documentation/filesystems/vfs.txt
index f49eecf2e573..623f094c9d8d 100644
--- a/Documentation/filesystems/vfs.txt
+++ b/Documentation/filesystems/vfs.txt
@@ -536,6 +536,7 @@ struct address_space_operations {
536 /* migrate the contents of a page to the specified target */ 536 /* migrate the contents of a page to the specified target */
537 int (*migratepage) (struct page *, struct page *); 537 int (*migratepage) (struct page *, struct page *);
538 int (*launder_page) (struct page *); 538 int (*launder_page) (struct page *);
539 int (*error_remove_page) (struct mapping *mapping, struct page *page);
539}; 540};
540 541
541 writepage: called by the VM to write a dirty page to backing store. 542 writepage: called by the VM to write a dirty page to backing store.
@@ -694,6 +695,12 @@ struct address_space_operations {
694 prevent redirtying the page, it is kept locked during the whole 695 prevent redirtying the page, it is kept locked during the whole
695 operation. 696 operation.
696 697
698 error_remove_page: normally set to generic_error_remove_page if truncation
699 is ok for this address space. Used for memory failure handling.
700 Setting this implies you deal with pages going away under you,
701 unless you have them locked or reference counts increased.
702
703
697The File Object 704The File Object
698=============== 705===============
699 706
diff --git a/include/linux/fs.h b/include/linux/fs.h
index b21cf6b9c80b..4f47afd37647 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -595,6 +595,7 @@ struct address_space_operations {
595 int (*launder_page) (struct page *); 595 int (*launder_page) (struct page *);
596 int (*is_partially_uptodate) (struct page *, read_descriptor_t *, 596 int (*is_partially_uptodate) (struct page *, read_descriptor_t *,
597 unsigned long); 597 unsigned long);
598 int (*error_remove_page)(struct address_space *, struct page *);
598}; 599};
599 600
600/* 601/*
diff --git a/include/linux/mm.h b/include/linux/mm.h
index b05bbde0296d..a16018f7d61c 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -795,6 +795,7 @@ extern int vmtruncate(struct inode * inode, loff_t offset);
795extern int vmtruncate_range(struct inode * inode, loff_t offset, loff_t end); 795extern int vmtruncate_range(struct inode * inode, loff_t offset, loff_t end);
796 796
797int truncate_inode_page(struct address_space *mapping, struct page *page); 797int truncate_inode_page(struct address_space *mapping, struct page *page);
798int generic_error_remove_page(struct address_space *mapping, struct page *page);
798 799
799int invalidate_inode_page(struct page *page); 800int invalidate_inode_page(struct page *page);
800 801
diff --git a/mm/truncate.c b/mm/truncate.c
index ea132f7ea2d2..a17b3977cfdf 100644
--- a/mm/truncate.c
+++ b/mm/truncate.c
@@ -147,6 +147,23 @@ int truncate_inode_page(struct address_space *mapping, struct page *page)
147} 147}
148 148
149/* 149/*
150 * Used to get rid of pages on hardware memory corruption.
151 */
152int generic_error_remove_page(struct address_space *mapping, struct page *page)
153{
154 if (!mapping)
155 return -EINVAL;
156 /*
157 * Only punch for normal data pages for now.
158 * Handling other types like directories would need more auditing.
159 */
160 if (!S_ISREG(mapping->host->i_mode))
161 return -EIO;
162 return truncate_inode_page(mapping, page);
163}
164EXPORT_SYMBOL(generic_error_remove_page);
165
166/*
150 * Safely invalidate one page from its pagecache mapping. 167 * Safely invalidate one page from its pagecache mapping.
151 * It only drops clean, unused pages. The page must be locked. 168 * It only drops clean, unused pages. The page must be locked.
152 * 169 *