import PULS_20160108
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / fs / ubifs / replay.c
index 94d78fc5d4e0dc11e6ea4db670f43853f569eabb..05cf1e64618acbaa8142618fc5ee27eb8aa0ed8f 100644 (file)
@@ -141,9 +141,9 @@ static int set_bud_lprops(struct ubifs_info *c, struct bud_entry *b)
                 * during the replay.
                 */
                if (dirty != 0)
-                       dbg_msg("LEB %d lp: %d free %d dirty "
-                               "replay: %d free %d dirty", b->bud->lnum,
-                               lp->free, lp->dirty, b->free, b->dirty);
+                       dbg_mnt("LEB %d lp: %d free %d dirty replay: %d free %d dirty",
+                               b->bud->lnum, lp->free, lp->dirty, b->free,
+                               b->dirty);
        }
        lp = ubifs_change_lp(c, lp, b->free, dirty + b->dirty,
                             lp->flags | LPROPS_TAKEN, 0);
@@ -152,6 +152,31 @@ static int set_bud_lprops(struct ubifs_info *c, struct bud_entry *b)
                goto out;
        }
 
+//MTK start
+       if (c->need_recovery && b->free > 0) {
+               err = ubifs_leb_read(c, b->bud->lnum, c->sbuf, 0, c->leb_size - b->free, 0);
+               if(err) {
+                       switch(err) {
+                       case -EUCLEAN:
+                               /* shouldn't see this error, UBI will take care this*/
+                               goto skip_move;
+                       case -EBADMSG:
+                               /* copy if error == -EBADMSG */
+                               break;
+                       default:
+                               ubifs_err("cannot read %d bytes from LEB %d:%d,"
+                                         " error %d", c->leb_size - b->free, b->bud->lnum, 0, err);
+                               goto out;
+                       }
+               }
+               dbg_mnt("ubifs_leb_change LEB %d:%d\n",  b->bud->lnum, c->leb_size - b->free);
+               err = ubifs_leb_change(c, b->bud->lnum, c->sbuf, c->leb_size - b->free);
+               if(err) {
+                       ubifs_err("ubifs_leb_change LEB %d:%d fail\n",  b->bud->lnum, c->leb_size - b->free);
+               }
+       }
+skip_move:
+//MTK end
        /* Make sure the journal head points to the latest bud */
        err = ubifs_wbuf_seek_nolock(&c->jheads[b->bud->jhead].wbuf,
                                     b->bud->lnum, c->leb_size - b->free);
@@ -677,7 +702,8 @@ static int replay_bud(struct ubifs_info *c, struct bud_entry *b)
 
        b->dirty = sleb->endpt - offs - used;
        b->free = c->leb_size - sleb->endpt;
-       dbg_mnt("bud LEB %d replied: dirty %d, free %d", lnum, b->dirty, b->free);
+       dbg_mnt("bud LEB %d replied: dirty %d, free %d",
+               lnum, b->dirty, b->free);
 
 out:
        ubifs_scan_destroy(sleb);
@@ -849,8 +875,26 @@ static int replay_log_leb(struct ubifs_info *c, int lnum, int offs, void *sbuf)
                goto out;
        }
 
+#ifdef CONFIG_UBIFS_FS_FULL_USE_LOG_BACKWARD
+       /* Search the last cs node whose cmt_no is recorded in master node*/
+       list_for_each_entry_reverse(snod, &sleb->nodes, list) {
+               if(snod->type == UBIFS_CS_NODE)
+               {
+                       if(c->cs_sqnum == 0)
+                       {
+                               node = snod->node;
+                               if(le64_to_cpu(node->cmt_no) == c->cmt_no)
+                                       break;
+                       }
+                       else
+                               break;
+               }
+       }
+       node = snod->node;
+#else
        node = sleb->buf;
        snod = list_entry(sleb->nodes.next, struct ubifs_scan_node, list);
+#endif
        if (c->cs_sqnum == 0) {
                /*
                 * This is the first log LEB we are looking at, make sure that
@@ -865,8 +909,7 @@ static int replay_log_leb(struct ubifs_info *c, int lnum, int offs, void *sbuf)
                        goto out_dump;
                }
                if (le64_to_cpu(node->cmt_no) != c->cmt_no) {
-                       ubifs_err("first CS node at LEB %d:%d has wrong "
-                                 "commit number %llu expected %llu",
+                       ubifs_err("first CS node at LEB %d:%d has wrong commit number %llu expected %llu",
                                  lnum, offs,
                                  (unsigned long long)le64_to_cpu(node->cmt_no),
                                  c->cmt_no);
@@ -889,11 +932,13 @@ static int replay_log_leb(struct ubifs_info *c, int lnum, int offs, void *sbuf)
                goto out;
        }
 
+#ifndef CONFIG_UBIFS_FS_FULL_USE_LOG_BACKWARD
        /* Make sure the first node sits at offset zero of the LEB */
        if (snod->offs != 0) {
                ubifs_err("first node is not at zero offset");
                goto out_dump;
        }
+#endif
 
        list_for_each_entry(snod, &sleb->nodes, list) {
                cond_resched();
@@ -904,9 +949,17 @@ static int replay_log_leb(struct ubifs_info *c, int lnum, int offs, void *sbuf)
                }
 
                if (snod->sqnum < c->cs_sqnum) {
+#ifdef CONFIG_UBIFS_FS_FULL_USE_LOG_BACKWARD
+                       /*
+                        * Node with sqnum less than that of current cs already handled
+                        * skip current snod from adding.
+                        */
+                       continue;
+#else
                        ubifs_err("bad sqnum %llu, commit sqnum %llu",
                                  snod->sqnum, c->cs_sqnum);
                        goto out_dump;
+#endif
                }
 
                if (snod->sqnum > c->max_sqnum)
@@ -932,11 +985,15 @@ static int replay_log_leb(struct ubifs_info *c, int lnum, int offs, void *sbuf)
                        break;
                }
                case UBIFS_CS_NODE:
+#ifdef CONFIG_UBIFS_FS_FULL_USE_LOG_BACKWARD
+                       continue;
+#else
                        /* Make sure it sits at the beginning of LEB */
                        if (snod->offs != 0) {
                                ubifs_err("unexpected node in log");
                                goto out_dump;
                        }
+#endif
                        break;
                default:
                        ubifs_err("unexpected node in log");
@@ -1058,8 +1115,8 @@ int ubifs_replay_journal(struct ubifs_info *c)
        c->bi.uncommitted_idx *= c->max_idx_node_sz;
 
        ubifs_assert(c->bud_bytes <= c->max_bud_bytes || c->need_recovery);
-       dbg_mnt("finished, log head LEB %d:%d, max_sqnum %llu, "
-               "highest_inum %lu", c->lhead_lnum, c->lhead_offs, c->max_sqnum,
+       dbg_mnt("finished, log head LEB %d:%d, max_sqnum %llu, highest_inum %lu",
+               c->lhead_lnum, c->lhead_offs, c->max_sqnum,
                (unsigned long)c->highest_inum);
 out:
        destroy_replay_list(c);