Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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

+41 -7
+15 -7
drivers/mtd/ubi/eba.c
··· 575 575 int err, idx = vol_id2idx(ubi, vol_id), new_pnum, data_size, tries = 0; 576 576 struct ubi_volume *vol = ubi->volumes[idx]; 577 577 struct ubi_vid_hdr *vid_hdr; 578 + uint32_t crc; 578 579 579 580 vid_hdr = ubi_zalloc_vid_hdr(ubi, GFP_NOFS); 580 581 if (!vid_hdr) ··· 600 599 goto out_put; 601 600 } 602 601 603 - vid_hdr->sqnum = cpu_to_be64(ubi_next_sqnum(ubi)); 604 - err = ubi_io_write_vid_hdr(ubi, new_pnum, vid_hdr); 605 - if (err) { 606 - up_read(&ubi->fm_eba_sem); 607 - goto write_error; 608 - } 602 + ubi_assert(vid_hdr->vol_type == UBI_VID_DYNAMIC); 609 603 610 - data_size = offset + len; 611 604 mutex_lock(&ubi->buf_mutex); 612 605 memset(ubi->peb_buf + offset, 0xFF, len); 613 606 ··· 615 620 } 616 621 617 622 memcpy(ubi->peb_buf + offset, buf, len); 623 + 624 + data_size = offset + len; 625 + crc = crc32(UBI_CRC32_INIT, ubi->peb_buf, data_size); 626 + vid_hdr->sqnum = cpu_to_be64(ubi_next_sqnum(ubi)); 627 + vid_hdr->copy_flag = 1; 628 + vid_hdr->data_size = cpu_to_be32(data_size); 629 + vid_hdr->data_crc = cpu_to_be32(crc); 630 + err = ubi_io_write_vid_hdr(ubi, new_pnum, vid_hdr); 631 + if (err) { 632 + mutex_unlock(&ubi->buf_mutex); 633 + up_read(&ubi->fm_eba_sem); 634 + goto write_error; 635 + } 618 636 619 637 err = ubi_io_write_data(ubi, ubi->peb_buf, new_pnum, 0, data_size); 620 638 if (err) {
+24
fs/ubifs/file.c
··· 52 52 #include "ubifs.h" 53 53 #include <linux/mount.h> 54 54 #include <linux/slab.h> 55 + #include <linux/migrate.h> 55 56 56 57 static int read_block(struct inode *inode, void *addr, unsigned int block, 57 58 struct ubifs_data_node *dn) ··· 1453 1452 return ret; 1454 1453 } 1455 1454 1455 + #ifdef CONFIG_MIGRATION 1456 + static int ubifs_migrate_page(struct address_space *mapping, 1457 + struct page *newpage, struct page *page, enum migrate_mode mode) 1458 + { 1459 + int rc; 1460 + 1461 + rc = migrate_page_move_mapping(mapping, newpage, page, NULL, mode, 0); 1462 + if (rc != MIGRATEPAGE_SUCCESS) 1463 + return rc; 1464 + 1465 + if (PagePrivate(page)) { 1466 + ClearPagePrivate(page); 1467 + SetPagePrivate(newpage); 1468 + } 1469 + 1470 + migrate_page_copy(newpage, page); 1471 + return MIGRATEPAGE_SUCCESS; 1472 + } 1473 + #endif 1474 + 1456 1475 static int ubifs_releasepage(struct page *page, gfp_t unused_gfp_flags) 1457 1476 { 1458 1477 /* ··· 1612 1591 .write_end = ubifs_write_end, 1613 1592 .invalidatepage = ubifs_invalidatepage, 1614 1593 .set_page_dirty = ubifs_set_page_dirty, 1594 + #ifdef CONFIG_MIGRATION 1595 + .migratepage = ubifs_migrate_page, 1596 + #endif 1615 1597 .releasepage = ubifs_releasepage, 1616 1598 }; 1617 1599
+2
mm/migrate.c
··· 431 431 432 432 return MIGRATEPAGE_SUCCESS; 433 433 } 434 + EXPORT_SYMBOL(migrate_page_move_mapping); 434 435 435 436 /* 436 437 * The expected number of remaining references is the same as that ··· 587 586 588 587 mem_cgroup_migrate(page, newpage); 589 588 } 589 + EXPORT_SYMBOL(migrate_page_copy); 590 590 591 591 /************************************************************ 592 592 * Migration functions