Skip to content

Commit

Permalink
UBI: add ubi_leb_map interface
Browse files Browse the repository at this point in the history
The idea of this interface belongs to Adrian Hunter. The
interface is extremely useful when one has to have a guarantee
that an LEB will contain all 0xFFs even in case of an unclean
reboot. UBI does have an 'ubi_leb_erase()' call which may do
this, but it is stupid and ineffecient, because it flushes whole
queue. I should be re-worked to just be a pair of unmap,
map calls.

The user of the interfaci is UBIFS at the moment.

Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
  • Loading branch information
Artem Bityutskiy authored and Artem Bityutskiy committed Dec 26, 2007
1 parent 94780d4 commit 393852e
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 5 deletions.
13 changes: 8 additions & 5 deletions drivers/mtd/ubi/eba.c
Original file line number Diff line number Diff line change
Expand Up @@ -656,11 +656,14 @@ int ubi_eba_write_leb(struct ubi_device *ubi, int vol_id, int lnum,
goto write_error;
}

err = ubi_io_write_data(ubi, buf, pnum, offset, len);
if (err) {
ubi_warn("failed to write %d bytes at offset %d of LEB %d:%d, "
"PEB %d", len, offset, vol_id, lnum, pnum);
goto write_error;
if (len) {
err = ubi_io_write_data(ubi, buf, pnum, offset, len);
if (err) {
ubi_warn("failed to write %d bytes at offset %d of "
"LEB %d:%d, PEB %d", len, offset, vol_id,
lnum, pnum);
goto write_error;
}
}

vol->eba_tbl[lnum] = pnum;
Expand Down
45 changes: 45 additions & 0 deletions drivers/mtd/ubi/kapi.c
Original file line number Diff line number Diff line change
Expand Up @@ -546,6 +546,51 @@ int ubi_leb_unmap(struct ubi_volume_desc *desc, int lnum)
}
EXPORT_SYMBOL_GPL(ubi_leb_unmap);

/**
* ubi_leb_map - map logical erasblock to a physical eraseblock.
* @desc: volume descriptor
* @lnum: logical eraseblock number
* @dtype: expected data type
*
* This function maps an un-mapped logical eraseblock @lnum to a physical
* eraseblock. This means, that after a successfull invocation of this
* function the logical eraseblock @lnum will be empty (contain only %0xFF
* bytes) and be mapped to a physical eraseblock, even if an unclean reboot
* happens.
*
* This function returns zero in case of success, %-EBADF if the volume is
* damaged because of an interrupted update, %-EBADMSG if the logical
* eraseblock is already mapped, and other negative error codes in case of
* other failures.
*/
int ubi_leb_map(struct ubi_volume_desc *desc, int lnum, int dtype)
{
struct ubi_volume *vol = desc->vol;
struct ubi_device *ubi = vol->ubi;
int vol_id = vol->vol_id;

dbg_msg("unmap LEB %d:%d", vol_id, lnum);

if (desc->mode == UBI_READONLY || vol->vol_type == UBI_STATIC_VOLUME)
return -EROFS;

if (lnum < 0 || lnum >= vol->reserved_pebs)
return -EINVAL;

if (dtype != UBI_LONGTERM && dtype != UBI_SHORTTERM &&
dtype != UBI_UNKNOWN)
return -EINVAL;

if (vol->upd_marker)
return -EBADF;

if (vol->eba_tbl[lnum] >= 0)
return -EBADMSG;

return ubi_eba_write_leb(ubi, vol_id, lnum, NULL, 0, 0, dtype);
}
EXPORT_SYMBOL_GPL(ubi_leb_map);

/**
* ubi_is_mapped - check if logical eraseblock is mapped.
* @desc: volume descriptor
Expand Down
1 change: 1 addition & 0 deletions include/linux/mtd/ubi.h
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,7 @@ int ubi_leb_change(struct ubi_volume_desc *desc, int lnum, const void *buf,
int len, int dtype);
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);
int ubi_is_mapped(struct ubi_volume_desc *desc, int lnum);

/*
Expand Down

0 comments on commit 393852e

Please sign in to comment.