summaryrefslogtreecommitdiff
path: root/fs
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2016-06-23 22:48:48 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2016-06-23 22:48:48 -0700
commit63c04ee7d3b7c8d8e2726cb7c5f8a5f6fcc1e3b2 (patch)
tree8ead21ef2c7e84bcd30511d50925416018abd93e /fs
parent0bf0ea431f84bcf34facc5b1f792d000f5957565 (diff)
parent4ac1c17b2044a1b4b2fbed74451947e905fc2992 (diff)
downloadlinux-63c04ee7d3b7c8d8e2726cb7c5f8a5f6fcc1e3b2.tar.gz
Merge tag 'upstream-4.7-rc5' of git://git.infradead.org/linux-ubifs
Pull UBI/UBIFS fixes from Richard Weinberger: "This contains fixes for two critical bugs in UBI and UBIFS: - fix the possibility of losing data upon a power cut when UBI tries to recover from a write error - fix page migration on UBIFS. It turned out that the default page migration function is not suitable for UBIFS" * tag 'upstream-4.7-rc5' of git://git.infradead.org/linux-ubifs: UBIFS: Implement ->migratepage() mm: Export migrate_page_move_mapping and migrate_page_copy ubi: Make recover_peb power cut aware gpio: make library immune to error pointers gpio: make sure gpiod_to_irq() returns negative on NULL desc gpio: 104-idi-48: Fix missing spin_lock_init for ack_lock
Diffstat (limited to 'fs')
-rw-r--r--fs/ubifs/file.c24
1 files changed, 24 insertions, 0 deletions
diff --git a/fs/ubifs/file.c b/fs/ubifs/file.c
index 08316972ff93..7bbf420d1289 100644
--- a/fs/ubifs/file.c
+++ b/fs/ubifs/file.c
@@ -52,6 +52,7 @@
#include "ubifs.h"
#include <linux/mount.h>
#include <linux/slab.h>
+#include <linux/migrate.h>
static int read_block(struct inode *inode, void *addr, unsigned int block,
struct ubifs_data_node *dn)
@@ -1452,6 +1453,26 @@ static int ubifs_set_page_dirty(struct page *page)
return ret;
}
+#ifdef CONFIG_MIGRATION
+static int ubifs_migrate_page(struct address_space *mapping,
+ struct page *newpage, struct page *page, enum migrate_mode mode)
+{
+ int rc;
+
+ rc = migrate_page_move_mapping(mapping, newpage, page, NULL, mode, 0);
+ if (rc != MIGRATEPAGE_SUCCESS)
+ return rc;
+
+ if (PagePrivate(page)) {
+ ClearPagePrivate(page);
+ SetPagePrivate(newpage);
+ }
+
+ migrate_page_copy(newpage, page);
+ return MIGRATEPAGE_SUCCESS;
+}
+#endif
+
static int ubifs_releasepage(struct page *page, gfp_t unused_gfp_flags)
{
/*
@@ -1591,6 +1612,9 @@ const struct address_space_operations ubifs_file_address_operations = {
.write_end = ubifs_write_end,
.invalidatepage = ubifs_invalidatepage,
.set_page_dirty = ubifs_set_page_dirty,
+#ifdef CONFIG_MIGRATION
+ .migratepage = ubifs_migrate_page,
+#endif
.releasepage = ubifs_releasepage,
};