import PULS_20160108
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / fs / ubifs / replay.c
index 3187925e9879b29ad2530426fa4834eb9b1028fa..05cf1e64618acbaa8142618fc5ee27eb8aa0ed8f 100644 (file)
@@ -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);
@@ -850,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
@@ -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");