aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2016-06-24 01:48:48 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2016-06-24 01:48:48 -0400
commit63c04ee7d3b7c8d8e2726cb7c5f8a5f6fcc1e3b2 (patch)
tree8ead21ef2c7e84bcd30511d50925416018abd93e
parent0bf0ea431f84bcf34facc5b1f792d000f5957565 (diff)
parent4ac1c17b2044a1b4b2fbed74451947e905fc2992 (diff)
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
-rw-r--r--drivers/mtd/ubi/eba.c22
-rw-r--r--fs/ubifs/file.c24
-rw-r--r--mm/migrate.c2
3 files changed, 41 insertions, 7 deletions
diff --git a/drivers/mtd/ubi/eba.c b/drivers/mtd/ubi/eba.c
index 5780dd1ba79d..ebf517271d29 100644
--- a/drivers/mtd/ubi/eba.c
+++ b/drivers/mtd/ubi/eba.c
@@ -575,6 +575,7 @@ static int recover_peb(struct ubi_device *ubi, int pnum, int vol_id, int lnum,
575 int err, idx = vol_id2idx(ubi, vol_id), new_pnum, data_size, tries = 0; 575 int err, idx = vol_id2idx(ubi, vol_id), new_pnum, data_size, tries = 0;
576 struct ubi_volume *vol = ubi->volumes[idx]; 576 struct ubi_volume *vol = ubi->volumes[idx];
577 struct ubi_vid_hdr *vid_hdr; 577 struct ubi_vid_hdr *vid_hdr;
578 uint32_t crc;
578 579
579 vid_hdr = ubi_zalloc_vid_hdr(ubi, GFP_NOFS); 580 vid_hdr = ubi_zalloc_vid_hdr(ubi, GFP_NOFS);
580 if (!vid_hdr) 581 if (!vid_hdr)
@@ -599,14 +600,8 @@ retry:
599 goto out_put; 600 goto out_put;
600 } 601 }
601 602
602 vid_hdr->sqnum = cpu_to_be64(ubi_next_sqnum(ubi)); 603 ubi_assert(vid_hdr->vol_type == UBI_VID_DYNAMIC);
603 err = ubi_io_write_vid_hdr(ubi, new_pnum, vid_hdr);
604 if (err) {
605 up_read(&ubi->fm_eba_sem);
606 goto write_error;
607 }
608 604
609 data_size = offset + len;
610 mutex_lock(&ubi->buf_mutex); 605 mutex_lock(&ubi->buf_mutex);
611 memset(ubi->peb_buf + offset, 0xFF, len); 606 memset(ubi->peb_buf + offset, 0xFF, len);
612 607
@@ -621,6 +616,19 @@ retry:
621 616
622 memcpy(ubi->peb_buf + offset, buf, len); 617 memcpy(ubi->peb_buf + offset, buf, len);
623 618
619 data_size = offset + len;
620 crc = crc32(UBI_CRC32_INIT, ubi->peb_buf, data_size);
621 vid_hdr->sqnum = cpu_to_be64(ubi_next_sqnum(ubi));
622 vid_hdr->copy_flag = 1;
623 vid_hdr->data_size = cpu_to_be32(data_size);
624 vid_hdr->data_crc = cpu_to_be32(crc);
625 err = ubi_io_write_vid_hdr(ubi, new_pnum, vid_hdr);
626 if (err) {
627 mutex_unlock(&ubi->buf_mutex);
628 up_read(&ubi->fm_eba_sem);
629 goto write_error;
630 }
631
624 err = ubi_io_write_data(ubi, ubi->peb_buf, new_pnum, 0, data_size); 632 err = ubi_io_write_data(ubi, ubi->peb_buf, new_pnum, 0, data_size);
625 if (err) { 633 if (err) {
626 mutex_unlock(&ubi->buf_mutex); 634 mutex_unlock(&ubi->buf_mutex);
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 @@
52#include "ubifs.h" 52#include "ubifs.h"
53#include <linux/mount.h> 53#include <linux/mount.h>
54#include <linux/slab.h> 54#include <linux/slab.h>
55#include <linux/migrate.h>
55 56
56static int read_block(struct inode *inode, void *addr, unsigned int block, 57static int read_block(struct inode *inode, void *addr, unsigned int block,
57 struct ubifs_data_node *dn) 58 struct ubifs_data_node *dn)
@@ -1452,6 +1453,26 @@ static int ubifs_set_page_dirty(struct page *page)
1452 return ret; 1453 return ret;
1453} 1454}
1454 1455
1456#ifdef CONFIG_MIGRATION
1457static int ubifs_migrate_page(struct address_space *mapping,
1458 struct page *newpage, struct page *page, enum migrate_mode mode)
1459{
1460 int rc;
1461
1462 rc = migrate_page_move_mapping(mapping, newpage, page, NULL, mode, 0);
1463 if (rc != MIGRATEPAGE_SUCCESS)
1464 return rc;
1465
1466 if (PagePrivate(page)) {
1467 ClearPagePrivate(page);
1468 SetPagePrivate(newpage);
1469 }
1470
1471 migrate_page_copy(newpage, page);
1472 return MIGRATEPAGE_SUCCESS;
1473}
1474#endif
1475
1455static int ubifs_releasepage(struct page *page, gfp_t unused_gfp_flags) 1476static int ubifs_releasepage(struct page *page, gfp_t unused_gfp_flags)
1456{ 1477{
1457 /* 1478 /*
@@ -1591,6 +1612,9 @@ const struct address_space_operations ubifs_file_address_operations = {
1591 .write_end = ubifs_write_end, 1612 .write_end = ubifs_write_end,
1592 .invalidatepage = ubifs_invalidatepage, 1613 .invalidatepage = ubifs_invalidatepage,
1593 .set_page_dirty = ubifs_set_page_dirty, 1614 .set_page_dirty = ubifs_set_page_dirty,
1615#ifdef CONFIG_MIGRATION
1616 .migratepage = ubifs_migrate_page,
1617#endif
1594 .releasepage = ubifs_releasepage, 1618 .releasepage = ubifs_releasepage,
1595}; 1619};
1596 1620
diff --git a/mm/migrate.c b/mm/migrate.c
index 9baf41c877ff..bd3fdc202e8b 100644
--- a/mm/migrate.c
+++ b/mm/migrate.c
@@ -431,6 +431,7 @@ int migrate_page_move_mapping(struct address_space *mapping,
431 431
432 return MIGRATEPAGE_SUCCESS; 432 return MIGRATEPAGE_SUCCESS;
433} 433}
434EXPORT_SYMBOL(migrate_page_move_mapping);
434 435
435/* 436/*
436 * The expected number of remaining references is the same as that 437 * The expected number of remaining references is the same as that
@@ -586,6 +587,7 @@ void migrate_page_copy(struct page *newpage, struct page *page)
586 587
587 mem_cgroup_migrate(page, newpage); 588 mem_cgroup_migrate(page, newpage);
588} 589}
590EXPORT_SYMBOL(migrate_page_copy);
589 591
590/************************************************************ 592/************************************************************
591 * Migration functions 593 * Migration functions