Hi, what happen if there is a power cut between the atomic update and the erase ? Is the leb is deleted during the recovery ? Matthieu Joel Reardon a écrit : > This is a proposal for adding an immediate mode for atomic updates of LEBs in > UBI. The idea is that, if the erase parameter is non-zero, then the old PEB will > be erase after the new PEB is written, but before the function returns. It > will not go into a work queue. This is for security-relevant situations where, > for instance, the user needs assurance that sensitive information on an > eraseblock is actually gone after the update. > > The function schedule_erase always returns zero, because the actual error > during erasure is not known at the time. Now, if it is immediate, then it has > the ability to return an error if that fails. This would mean some functions > higher up (i.e., change_leb), will be able to return "old PEB is now bad" > messages, indicating that the secure erasure has failed. I want to check now > that this would be okay, or should the old PEB fail be ignored, or handled in > some other way. > > Signed-off-by: Joel Reardon <reardonj@xxxxxxxxxxx> > --- > drivers/mtd/ubi/eba.c | 20 +++++++++++--------- > drivers/mtd/ubi/kapi.c | 7 ++++--- > drivers/mtd/ubi/ubi.h | 5 +++-- > drivers/mtd/ubi/upd.c | 5 +++-- > drivers/mtd/ubi/wl.c | 25 +++++++++++++++---------- > fs/ubifs/debug.c | 4 ++-- > fs/ubifs/debug.h | 2 +- > fs/ubifs/io.c | 6 +++--- > fs/ubifs/log.c | 5 +++-- > fs/ubifs/lpt.c | 10 +++++----- > fs/ubifs/orphan.c | 2 +- > fs/ubifs/recovery.c | 12 ++++++------ > fs/ubifs/sb.c | 4 ++-- > fs/ubifs/tnc_commit.c | 2 +- > fs/ubifs/ubifs.h | 2 +- > include/linux/mtd/ubi.h | 6 +++--- > 16 files changed, 64 insertions(+), 53 deletions(-) > > diff --git a/drivers/mtd/ubi/eba.c b/drivers/mtd/ubi/eba.c > index cd26da8..6e44cfe 100644 > --- a/drivers/mtd/ubi/eba.c > +++ b/drivers/mtd/ubi/eba.c > @@ -341,7 +341,7 @@ int ubi_eba_unmap_leb(struct ubi_device *ubi, struct ubi_volume *vol, > dbg_eba("erase LEB %d:%d, PEB %d", vol_id, lnum, pnum); > > vol->eba_tbl[lnum] = UBI_LEB_UNMAPPED; > - err = ubi_wl_put_peb(ubi, pnum, 0); > + err = ubi_wl_put_peb(ubi, pnum, 0, 0); > > out_unlock: > leb_write_unlock(ubi, vol_id, lnum); > @@ -550,7 +550,7 @@ retry: > ubi_free_vid_hdr(ubi, vid_hdr); > > vol->eba_tbl[lnum] = new_pnum; > - ubi_wl_put_peb(ubi, pnum, 1); > + ubi_wl_put_peb(ubi, pnum, 1, 0); > > ubi_msg("data was successfully recovered"); > return 0; > @@ -558,7 +558,7 @@ retry: > out_unlock: > mutex_unlock(&ubi->buf_mutex); > out_put: > - ubi_wl_put_peb(ubi, new_pnum, 1); > + ubi_wl_put_peb(ubi, new_pnum, 1, 0); > ubi_free_vid_hdr(ubi, vid_hdr); > return err; > > @@ -568,7 +568,7 @@ write_error: > * get another one. > */ > ubi_warn("failed to write to PEB %d", new_pnum); > - ubi_wl_put_peb(ubi, new_pnum, 1); > + ubi_wl_put_peb(ubi, new_pnum, 1, 0); > if (++tries > UBI_IO_RETRIES) { > ubi_free_vid_hdr(ubi, vid_hdr); > return err; > @@ -687,7 +687,7 @@ write_error: > * eraseblock, so just put it and request a new one. We assume that if > * this physical eraseblock went bad, the erase code will handle that. > */ > - err = ubi_wl_put_peb(ubi, pnum, 1); > + err = ubi_wl_put_peb(ubi, pnum, 1, 0); > if (err || ++tries > UBI_IO_RETRIES) { > ubi_ro_mode(ubi); > leb_write_unlock(ubi, vol_id, lnum); > @@ -807,7 +807,7 @@ write_error: > return err; > } > > - err = ubi_wl_put_peb(ubi, pnum, 1); > + err = ubi_wl_put_peb(ubi, pnum, 1, 0); > if (err || ++tries > UBI_IO_RETRIES) { > ubi_ro_mode(ubi); > leb_write_unlock(ubi, vol_id, lnum); > @@ -828,6 +828,7 @@ write_error: > * @buf: data to write > * @len: how many bytes to write > * @dtype: data type > + * @erase: if this physical eraseblock should be syncronously erased > * > * This function changes the contents of a logical eraseblock atomically. @buf > * has to contain new logical eraseblock data, and @len - the length of the > @@ -839,7 +840,8 @@ write_error: > * LEB change may be done at a time. This is ensured by @ubi->alc_mutex. > */ > int ubi_eba_atomic_leb_change(struct ubi_device *ubi, struct ubi_volume *vol, > - int lnum, const void *buf, int len, int dtype) > + int lnum, const void *buf, int len, int dtype, > + int erase) > { > int err, pnum, tries = 0, vol_id = vol->vol_id; > struct ubi_vid_hdr *vid_hdr; > @@ -905,7 +907,7 @@ retry: > } > > if (vol->eba_tbl[lnum] >= 0) { > - err = ubi_wl_put_peb(ubi, vol->eba_tbl[lnum], 0); > + err = ubi_wl_put_peb(ubi, vol->eba_tbl[lnum], 0, erase); > if (err) > goto out_leb_unlock; > } > @@ -930,7 +932,7 @@ write_error: > goto out_leb_unlock; > } > > - err = ubi_wl_put_peb(ubi, pnum, 1); > + err = ubi_wl_put_peb(ubi, pnum, 1, erase); > if (err || ++tries > UBI_IO_RETRIES) { > ubi_ro_mode(ubi); > goto out_leb_unlock; > diff --git a/drivers/mtd/ubi/kapi.c b/drivers/mtd/ubi/kapi.c > index 9fdb353..7be2044 100644 > --- a/drivers/mtd/ubi/kapi.c > +++ b/drivers/mtd/ubi/kapi.c > @@ -487,6 +487,7 @@ EXPORT_SYMBOL_GPL(ubi_leb_write); > * @buf: data to write > * @len: how many bytes to write > * @dtype: expected data type > + * @erase: if non-zero then blocks until old block is erased > * > * This function changes the contents of a logical eraseblock atomically. @buf > * has to contain new logical eraseblock data, and @len - the length of the > @@ -497,7 +498,7 @@ EXPORT_SYMBOL_GPL(ubi_leb_write); > * code in case of failure. > */ > int ubi_leb_change(struct ubi_volume_desc *desc, int lnum, const void *buf, > - int len, int dtype) > + int len, int dtype, int erase) > { > struct ubi_volume *vol = desc->vol; > struct ubi_device *ubi = vol->ubi; > @@ -524,8 +525,8 @@ int ubi_leb_change(struct ubi_volume_desc *desc, int lnum, const void *buf, > > if (len == 0) > return 0; > - > - return ubi_eba_atomic_leb_change(ubi, vol, lnum, buf, len, dtype); > + return ubi_eba_atomic_leb_change(ubi, vol, lnum, buf, > + len, dtype, erase); > } > EXPORT_SYMBOL_GPL(ubi_leb_change); > > diff --git a/drivers/mtd/ubi/ubi.h b/drivers/mtd/ubi/ubi.h > index d51d75d..cbe9082 100644 > --- a/drivers/mtd/ubi/ubi.h > +++ b/drivers/mtd/ubi/ubi.h > @@ -532,14 +532,15 @@ int ubi_eba_write_leb_st(struct ubi_device *ubi, struct ubi_volume *vol, > int lnum, const void *buf, int len, int dtype, > int used_ebs); > int ubi_eba_atomic_leb_change(struct ubi_device *ubi, struct ubi_volume *vol, > - int lnum, const void *buf, int len, int dtype); > + int lnum, const void *buf, int len, int dtype, > + int erase); > int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to, > struct ubi_vid_hdr *vid_hdr); > int ubi_eba_init_scan(struct ubi_device *ubi, struct ubi_scan_info *si); > > /* wl.c */ > int ubi_wl_get_peb(struct ubi_device *ubi, int dtype); > -int ubi_wl_put_peb(struct ubi_device *ubi, int pnum, int torture); > +int ubi_wl_put_peb(struct ubi_device *ubi, int pnum, int torture, int erase); > int ubi_wl_flush(struct ubi_device *ubi); > int ubi_wl_scrub_peb(struct ubi_device *ubi, int pnum); > int ubi_wl_init_scan(struct ubi_device *ubi, struct ubi_scan_info *si); > diff --git a/drivers/mtd/ubi/upd.c b/drivers/mtd/ubi/upd.c > index 425bf5a..7584aed 100644 > --- a/drivers/mtd/ubi/upd.c > +++ b/drivers/mtd/ubi/upd.c > @@ -187,7 +187,7 @@ int ubi_start_leb_change(struct ubi_device *ubi, struct ubi_volume *vol, > vol->vol_id, req->lnum, req->bytes); > if (req->bytes == 0) > return ubi_eba_atomic_leb_change(ubi, vol, req->lnum, NULL, 0, > - req->dtype); > + req->dtype, 0); > > vol->upd_bytes = req->bytes; > vol->upd_received = 0; > @@ -421,7 +421,8 @@ int ubi_more_leb_change_data(struct ubi_device *ubi, struct ubi_volume *vol, > len - vol->upd_bytes); > len = ubi_calc_data_len(ubi, vol->upd_buf, len); > err = ubi_eba_atomic_leb_change(ubi, vol, vol->ch_lnum, > - vol->upd_buf, len, UBI_UNKNOWN); > + vol->upd_buf, len, > + UBI_UNKNOWN, 0); > if (err) > return err; > } > diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c > index 0696e36..fa973f6 100644 > --- a/drivers/mtd/ubi/wl.c > +++ b/drivers/mtd/ubi/wl.c > @@ -469,7 +469,6 @@ retry: > ubi_err("new PEB %d does not contain all 0xFF bytes", e->pnum); > return err; > } > - > return e->pnum; > } > > @@ -629,12 +628,13 @@ static int erase_worker(struct ubi_device *ubi, struct ubi_work *wl_wrk, > * @ubi: UBI device description object > * @e: the WL entry of the physical eraseblock to erase > * @torture: if the physical eraseblock has to be tortured > + * @blocking: schedule the work immediately and return after completion > * > * This function returns zero in case of success and a %-ENOMEM in case of > * failure. > */ > static int schedule_erase(struct ubi_device *ubi, struct ubi_wl_entry *e, > - int torture) > + int torture, int blocking) > { > struct ubi_work *wl_wrk; > > @@ -649,7 +649,11 @@ static int schedule_erase(struct ubi_device *ubi, struct ubi_wl_entry *e, > wl_wrk->e = e; > wl_wrk->torture = torture; > > - schedule_ubi_work(ubi, wl_wrk); > + if (blocking) > + erase_worker(ubi, wl_wrk, 0); > + else > + schedule_ubi_work(ubi, wl_wrk); > + > return 0; > } > > @@ -847,7 +851,7 @@ static int wear_leveling_worker(struct ubi_device *ubi, struct ubi_work *wrk, > ubi->move_to_put = ubi->wl_scheduled = 0; > spin_unlock(&ubi->wl_lock); > > - err = schedule_erase(ubi, e1, 0); > + err = schedule_erase(ubi, e1, 0, 0); > if (err) { > kmem_cache_free(ubi_wl_entry_slab, e1); > if (e2) > @@ -862,7 +866,7 @@ static int wear_leveling_worker(struct ubi_device *ubi, struct ubi_work *wrk, > */ > dbg_wl("PEB %d (LEB %d:%d) was put meanwhile, erase", > e2->pnum, vol_id, lnum); > - err = schedule_erase(ubi, e2, 0); > + err = schedule_erase(ubi, e2, 0, 0); > if (err) { > kmem_cache_free(ubi_wl_entry_slab, e2); > goto out_ro; > @@ -901,7 +905,7 @@ out_not_moved: > spin_unlock(&ubi->wl_lock); > > ubi_free_vid_hdr(ubi, vid_hdr); > - err = schedule_erase(ubi, e2, torture); > + err = schedule_erase(ubi, e2, torture, 0); > if (err) { > kmem_cache_free(ubi_wl_entry_slab, e2); > goto out_ro; > @@ -1058,7 +1062,7 @@ static int erase_worker(struct ubi_device *ubi, struct ubi_work *wl_wrk, > int err1; > > /* Re-schedule the LEB for erasure */ > - err1 = schedule_erase(ubi, e, 0); > + err1 = schedule_erase(ubi, e, 0, 0); > if (err1) { > err = err1; > goto out_ro; > @@ -1128,13 +1132,14 @@ out_ro: > * @ubi: UBI device description object > * @pnum: physical eraseblock to return > * @torture: if this physical eraseblock has to be tortured > + * @erase: if this physical eraseblock should be synchronously erased > * > * This function is called to return physical eraseblock @pnum to the pool of > * free physical eraseblocks. The @torture flag has to be set if an I/O error > * occurred to this @pnum and it has to be tested. This function returns zero > * in case of success, and a negative error code in case of failure. > */ > -int ubi_wl_put_peb(struct ubi_device *ubi, int pnum, int torture) > +int ubi_wl_put_peb(struct ubi_device *ubi, int pnum, int torture, int erase) > { > int err; > struct ubi_wl_entry *e; > @@ -1199,8 +1204,8 @@ retry: > } > } > spin_unlock(&ubi->wl_lock); > + err = schedule_erase(ubi, e, torture, erase); > > - err = schedule_erase(ubi, e, torture); > if (err) { > spin_lock(&ubi->wl_lock); > wl_tree_add(e, &ubi->used); > @@ -1465,7 +1470,7 @@ int ubi_wl_init_scan(struct ubi_device *ubi, struct ubi_scan_info *si) > e->pnum = seb->pnum; > e->ec = seb->ec; > ubi->lookuptbl[e->pnum] = e; > - if (schedule_erase(ubi, e, 0)) { > + if (schedule_erase(ubi, e, 0, 0)) { > kmem_cache_free(ubi_wl_entry_slab, e); > goto out_free; > } > diff --git a/fs/ubifs/debug.c b/fs/ubifs/debug.c > index 1934084..415a04f 100644 > --- a/fs/ubifs/debug.c > +++ b/fs/ubifs/debug.c > @@ -2697,7 +2697,7 @@ int dbg_leb_write(struct ubifs_info *c, int lnum, const void *buf, > } > > int dbg_leb_change(struct ubifs_info *c, int lnum, const void *buf, > - int len, int dtype) > + int len, int dtype, int erase) > { > int err; > > @@ -2705,7 +2705,7 @@ int dbg_leb_change(struct ubifs_info *c, int lnum, const void *buf, > return -EROFS; > if (power_cut_emulated(c, lnum, 1)) > return -EROFS; > - err = ubi_leb_change(c->ubi, lnum, buf, len, dtype); > + err = ubi_leb_change(c->ubi, lnum, buf, len, dtype, erase); > if (err) > return err; > if (power_cut_emulated(c, lnum, 1)) > diff --git a/fs/ubifs/debug.h b/fs/ubifs/debug.h > index 9f71765..64950a7 100644 > --- a/fs/ubifs/debug.h > +++ b/fs/ubifs/debug.h > @@ -309,7 +309,7 @@ int dbg_check_nondata_nodes_order(struct ubifs_info *c, struct list_head *head); > int dbg_leb_write(struct ubifs_info *c, int lnum, const void *buf, int offs, > int len, int dtype); > int dbg_leb_change(struct ubifs_info *c, int lnum, const void *buf, int len, > - int dtype); > + int dtype, int erase); > int dbg_leb_unmap(struct ubifs_info *c, int lnum); > int dbg_leb_map(struct ubifs_info *c, int lnum, int dtype); > > diff --git a/fs/ubifs/io.c b/fs/ubifs/io.c > index 9228950..9ea6741 100644 > --- a/fs/ubifs/io.c > +++ b/fs/ubifs/io.c > @@ -136,7 +136,7 @@ int ubifs_leb_write(struct ubifs_info *c, int lnum, const void *buf, int offs, > } > > int ubifs_leb_change(struct ubifs_info *c, int lnum, const void *buf, int len, > - int dtype) > + int dtype, int erase) > { > int err; > > @@ -144,9 +144,9 @@ int ubifs_leb_change(struct ubifs_info *c, int lnum, const void *buf, int len, > if (c->ro_error) > return -EROFS; > if (!dbg_is_tst_rcvry(c)) > - err = ubi_leb_change(c->ubi, lnum, buf, len, dtype); > + err = ubi_leb_change(c->ubi, lnum, buf, len, dtype, erase); > else > - err = dbg_leb_change(c, lnum, buf, len, dtype); > + err = dbg_leb_change(c, lnum, buf, len, dtype, erase); > if (err) { > ubifs_err("changing %d bytes in LEB %d failed, error %d", > len, lnum, err); > diff --git a/fs/ubifs/log.c b/fs/ubifs/log.c > index f9fd068..a3d4660 100644 > --- a/fs/ubifs/log.c > +++ b/fs/ubifs/log.c > @@ -623,7 +623,7 @@ static int add_node(struct ubifs_info *c, void *buf, int *lnum, int *offs, > int sz = ALIGN(*offs, c->min_io_size), err; > > ubifs_pad(c, buf + *offs, sz - *offs); > - err = ubifs_leb_change(c, *lnum, buf, sz, UBI_SHORTTERM); > + err = ubifs_leb_change(c, *lnum, buf, sz, UBI_SHORTTERM, 0); > if (err) > return err; > *lnum = ubifs_next_log_lnum(c, *lnum); > @@ -702,7 +702,8 @@ int ubifs_consolidate_log(struct ubifs_info *c) > int sz = ALIGN(offs, c->min_io_size); > > ubifs_pad(c, buf + offs, sz - offs); > - err = ubifs_leb_change(c, write_lnum, buf, sz, UBI_SHORTTERM); > + err = ubifs_leb_change(c, write_lnum, buf, > + sz, UBI_SHORTTERM, 0); > if (err) > goto out_free; > offs = ALIGN(offs, c->min_io_size); > diff --git a/fs/ubifs/lpt.c b/fs/ubifs/lpt.c > index 66d59d0..c974211 100644 > --- a/fs/ubifs/lpt.c > +++ b/fs/ubifs/lpt.c > @@ -702,7 +702,7 @@ int ubifs_create_dflt_lpt(struct ubifs_info *c, int *main_lebs, int lpt_first, > set_ltab(c, lnum, c->leb_size - alen, alen - len); > memset(p, 0xff, alen - len); > err = ubifs_leb_change(c, lnum++, buf, alen, > - UBI_SHORTTERM); > + UBI_SHORTTERM, 0); > if (err) > goto out; > p = buf; > @@ -733,7 +733,7 @@ int ubifs_create_dflt_lpt(struct ubifs_info *c, int *main_lebs, int lpt_first, > alen - len); > memset(p, 0xff, alen - len); > err = ubifs_leb_change(c, lnum++, buf, alen, > - UBI_SHORTTERM); > + UBI_SHORTTERM, 0); > if (err) > goto out; > p = buf; > @@ -781,7 +781,7 @@ int ubifs_create_dflt_lpt(struct ubifs_info *c, int *main_lebs, int lpt_first, > set_ltab(c, lnum, c->leb_size - alen, alen - len); > memset(p, 0xff, alen - len); > err = ubifs_leb_change(c, lnum++, buf, alen, > - UBI_SHORTTERM); > + UBI_SHORTTERM, 0); > if (err) > goto out; > p = buf; > @@ -806,7 +806,7 @@ int ubifs_create_dflt_lpt(struct ubifs_info *c, int *main_lebs, int lpt_first, > alen = ALIGN(len, c->min_io_size); > set_ltab(c, lnum, c->leb_size - alen, alen - len); > memset(p, 0xff, alen - len); > - err = ubifs_leb_change(c, lnum++, buf, alen, UBI_SHORTTERM); > + err = ubifs_leb_change(c, lnum++, buf, alen, UBI_SHORTTERM, 0); > if (err) > goto out; > p = buf; > @@ -826,7 +826,7 @@ int ubifs_create_dflt_lpt(struct ubifs_info *c, int *main_lebs, int lpt_first, > > /* Write remaining buffer */ > memset(p, 0xff, alen - len); > - err = ubifs_leb_change(c, lnum, buf, alen, UBI_SHORTTERM); > + err = ubifs_leb_change(c, lnum, buf, alen, UBI_SHORTTERM, 0); > if (err) > goto out; > > diff --git a/fs/ubifs/orphan.c b/fs/ubifs/orphan.c > index c542c73..a0ec4ed 100644 > --- a/fs/ubifs/orphan.c > +++ b/fs/ubifs/orphan.c > @@ -249,7 +249,7 @@ static int do_write_orph_node(struct ubifs_info *c, int len, int atomic) > ubifs_prepare_node(c, c->orph_buf, len, 1); > len = ALIGN(len, c->min_io_size); > err = ubifs_leb_change(c, c->ohead_lnum, c->orph_buf, len, > - UBI_SHORTTERM); > + UBI_SHORTTERM, 0); > } else { > if (c->ohead_offs == 0) { > /* Ensure LEB has been unmapped */ > diff --git a/fs/ubifs/recovery.c b/fs/ubifs/recovery.c > index 2a935b3..0531112 100644 > --- a/fs/ubifs/recovery.c > +++ b/fs/ubifs/recovery.c > @@ -213,10 +213,10 @@ static int write_rcvrd_mst_node(struct ubifs_info *c, > mst->flags |= cpu_to_le32(UBIFS_MST_RCVRY); > > ubifs_prepare_node(c, mst, UBIFS_MST_NODE_SZ, 1); > - err = ubifs_leb_change(c, lnum, mst, sz, UBI_SHORTTERM); > + err = ubifs_leb_change(c, lnum, mst, sz, UBI_SHORTTERM, 0); > if (err) > goto out; > - err = ubifs_leb_change(c, lnum + 1, mst, sz, UBI_SHORTTERM); > + err = ubifs_leb_change(c, lnum + 1, mst, sz, UBI_SHORTTERM, 0); > if (err) > goto out; > out: > @@ -556,7 +556,7 @@ static int fix_unclean_leb(struct ubifs_info *c, struct ubifs_scan_leb *sleb, > } > } > err = ubifs_leb_change(c, lnum, sleb->buf, len, > - UBI_UNKNOWN); > + UBI_UNKNOWN, 0); > if (err) > return err; > } > @@ -941,7 +941,7 @@ static int recover_head(struct ubifs_info *c, int lnum, int offs, void *sbuf) > err = ubifs_leb_read(c, lnum, sbuf, 0, offs, 1); > if (err) > return err; > - return ubifs_leb_change(c, lnum, sbuf, offs, UBI_UNKNOWN); > + return ubifs_leb_change(c, lnum, sbuf, offs, UBI_UNKNOWN, 0); > } > > return 0; > @@ -1071,7 +1071,7 @@ static int clean_an_unclean_leb(struct ubifs_info *c, > } > > /* Write back the LEB atomically */ > - err = ubifs_leb_change(c, lnum, sbuf, len, UBI_UNKNOWN); > + err = ubifs_leb_change(c, lnum, sbuf, len, UBI_UNKNOWN, 0); > if (err) > return err; > > @@ -1472,7 +1472,7 @@ static int fix_size_in_place(struct ubifs_info *c, struct size_entry *e) > len -= 1; > len = ALIGN(len + 1, c->min_io_size); > /* Atomically write the fixed LEB back again */ > - err = ubifs_leb_change(c, lnum, c->sbuf, len, UBI_UNKNOWN); > + err = ubifs_leb_change(c, lnum, c->sbuf, len, UBI_UNKNOWN, 0); > if (err) > goto out; > dbg_rcvry("inode %lu at %d:%d size %lld -> %lld", > diff --git a/fs/ubifs/sb.c b/fs/ubifs/sb.c > index 771f7fb..e38d72e 100644 > --- a/fs/ubifs/sb.c > +++ b/fs/ubifs/sb.c > @@ -518,7 +518,7 @@ int ubifs_write_sb_node(struct ubifs_info *c, struct ubifs_sb_node *sup) > int len = ALIGN(UBIFS_SB_NODE_SZ, c->min_io_size); > > ubifs_prepare_node(c, sup, UBIFS_SB_NODE_SZ, 1); > - return ubifs_leb_change(c, UBIFS_SB_LNUM, sup, len, UBI_LONGTERM); > + return ubifs_leb_change(c, UBIFS_SB_LNUM, sup, len, UBI_LONGTERM, 0); > } > > /** > @@ -691,7 +691,7 @@ static int fixup_leb(struct ubifs_info *c, int lnum, int len) > if (err) > return err; > > - return ubifs_leb_change(c, lnum, c->sbuf, len, UBI_UNKNOWN); > + return ubifs_leb_change(c, lnum, c->sbuf, len, UBI_UNKNOWN, 0); > } > > /** > diff --git a/fs/ubifs/tnc_commit.c b/fs/ubifs/tnc_commit.c > index 4c15f07..485a283 100644 > --- a/fs/ubifs/tnc_commit.c > +++ b/fs/ubifs/tnc_commit.c > @@ -323,7 +323,7 @@ static int layout_leb_in_gaps(struct ubifs_info *c, int *p) > if (err) > return err; > err = ubifs_leb_change(c, lnum, c->ileb_buf, c->ileb_len, > - UBI_SHORTTERM); > + UBI_SHORTTERM, 1); > if (err) > return err; > dbg_gc("LEB %d wrote %d index nodes", lnum, tot_written); > diff --git a/fs/ubifs/ubifs.h b/fs/ubifs/ubifs.h > index 0cc1180..d7a2827 100644 > --- a/fs/ubifs/ubifs.h > +++ b/fs/ubifs/ubifs.h > @@ -1470,7 +1470,7 @@ int ubifs_leb_read(const struct ubifs_info *c, int lnum, void *buf, int offs, > int ubifs_leb_write(struct ubifs_info *c, int lnum, const void *buf, int offs, > int len, int dtype); > int ubifs_leb_change(struct ubifs_info *c, int lnum, const void *buf, int len, > - int dtype); > + int dtype, int erase); > int ubifs_leb_unmap(struct ubifs_info *c, int lnum); > int ubifs_leb_map(struct ubifs_info *c, int lnum, int dtype); > int ubifs_is_mapped(const struct ubifs_info *c, int lnum); > diff --git a/include/linux/mtd/ubi.h b/include/linux/mtd/ubi.h > index db4836b..2387c8a 100644 > --- a/include/linux/mtd/ubi.h > +++ b/include/linux/mtd/ubi.h > @@ -210,7 +210,7 @@ int ubi_leb_read(struct ubi_volume_desc *desc, int lnum, char *buf, int offset, > int ubi_leb_write(struct ubi_volume_desc *desc, int lnum, const void *buf, > int offset, int len, int dtype); > int ubi_leb_change(struct ubi_volume_desc *desc, int lnum, const void *buf, > - int len, int dtype); > + int len, int dtype, int erase); > int ubi_leb_erase(struct ubi_volume_desc *desc, int lnum); > int ubi_leb_unmap(struct ubi_volume_desc *desc, int lnum); > int ubi_leb_map(struct ubi_volume_desc *desc, int lnum, int dtype); > @@ -239,12 +239,12 @@ static inline int ubi_write(struct ubi_volume_desc *desc, int lnum, > > /* > * This function is the same as the 'ubi_leb_change()' functions, but it does > - * not have the data type argument. > + * not have the data type argument or the immediate erase argument. > */ > static inline int ubi_change(struct ubi_volume_desc *desc, int lnum, > const void *buf, int len) > { > - return ubi_leb_change(desc, lnum, buf, len, UBI_UNKNOWN); > + return ubi_leb_change(desc, lnum, buf, len, UBI_UNKNOWN, 0); > } > > #endif /* !__LINUX_UBI_H__ */ > -- > 1.7.5.4 > > > ______________________________________________________ > Linux MTD discussion mailing list > http://lists.infradead.org/mailman/listinfo/linux-mtd/ > -- To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html