Merge branch 'for-linus' of git://git.infradead.org/ubifs-2.6

* 'for-linus' of git://git.infradead.org/ubifs-2.6:
UBIFS: fix master node recovery
UBIFS: fix false assertion warning in case of I/O failures
UBIFS: fix false space checking failure

+47 -8
+26
fs/ubifs/recovery.c
··· 317 317 goto out_free; 318 318 } 319 319 memcpy(c->rcvrd_mst_node, c->mst_node, UBIFS_MST_NODE_SZ); 320 + 321 + /* 322 + * We had to recover the master node, which means there was an 323 + * unclean reboot. However, it is possible that the master node 324 + * is clean at this point, i.e., %UBIFS_MST_DIRTY is not set. 325 + * E.g., consider the following chain of events: 326 + * 327 + * 1. UBIFS was cleanly unmounted, so the master node is clean 328 + * 2. UBIFS is being mounted R/W and starts changing the master 329 + * node in the first (%UBIFS_MST_LNUM). A power cut happens, 330 + * so this LEB ends up with some amount of garbage at the 331 + * end. 332 + * 3. UBIFS is being mounted R/O. We reach this place and 333 + * recover the master node from the second LEB 334 + * (%UBIFS_MST_LNUM + 1). But we cannot update the media 335 + * because we are being mounted R/O. We have to defer the 336 + * operation. 337 + * 4. However, this master node (@c->mst_node) is marked as 338 + * clean (since the step 1). And if we just return, the 339 + * mount code will be confused and won't recover the master 340 + * node when it is re-mounter R/W later. 341 + * 342 + * Thus, to force the recovery by marking the master node as 343 + * dirty. 344 + */ 345 + c->mst_node->flags |= cpu_to_le32(UBIFS_MST_DIRTY); 320 346 } else { 321 347 /* Write the recovered master node */ 322 348 c->max_sqnum = le64_to_cpu(mst->ch.sqnum) - 1;
+21 -8
fs/ubifs/super.c
··· 1671 1671 if (err) 1672 1672 goto out; 1673 1673 1674 + dbg_gen("re-mounted read-write"); 1675 + c->remounting_rw = 0; 1676 + 1674 1677 if (c->need_recovery) { 1675 1678 c->need_recovery = 0; 1676 1679 ubifs_msg("deferred recovery completed"); 1680 + } else { 1681 + /* 1682 + * Do not run the debugging space check if the were doing 1683 + * recovery, because when we saved the information we had the 1684 + * file-system in a state where the TNC and lprops has been 1685 + * modified in memory, but all the I/O operations (including a 1686 + * commit) were deferred. So the file-system was in 1687 + * "non-committed" state. Now the file-system is in committed 1688 + * state, and of course the amount of free space will change 1689 + * because, for example, the old index size was imprecise. 1690 + */ 1691 + err = dbg_check_space_info(c); 1677 1692 } 1678 - 1679 - dbg_gen("re-mounted read-write"); 1680 - c->remounting_rw = 0; 1681 - err = dbg_check_space_info(c); 1682 1693 mutex_unlock(&c->umount_mutex); 1683 1694 return err; 1684 1695 ··· 1772 1761 * of the media. For example, there will be dirty inodes if we failed 1773 1762 * to write them back because of I/O errors. 1774 1763 */ 1775 - ubifs_assert(atomic_long_read(&c->dirty_pg_cnt) == 0); 1776 - ubifs_assert(c->budg_idx_growth == 0); 1777 - ubifs_assert(c->budg_dd_growth == 0); 1778 - ubifs_assert(c->budg_data_growth == 0); 1764 + if (!c->ro_error) { 1765 + ubifs_assert(atomic_long_read(&c->dirty_pg_cnt) == 0); 1766 + ubifs_assert(c->budg_idx_growth == 0); 1767 + ubifs_assert(c->budg_dd_growth == 0); 1768 + ubifs_assert(c->budg_data_growth == 0); 1769 + } 1779 1770 1780 1771 /* 1781 1772 * The 'c->umount_lock' prevents races between UBIFS memory shrinker