Commit 574c3fda authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'linux-next' of git://git.infradead.org/~dedekind/ubi-2.6

* 'linux-next' of git://git.infradead.org/~dedekind/ubi-2.6:
  UBI: fix checkpatch.pl warnings
  UBI: simplify PEB protection code
  UBI: prepare for protection tree improvements
  UBI: return -ENOMEM upon failing vmalloc
  UBI: document UBI ioctls
  UBI: handle write errors in WL worker
  UBI: fix error path
  UBI: some code re-structuring
  UBI: fix deadlock
  UBI: fix warnings when debugging is enabled
parents 56635f7e f2863c54
...@@ -97,6 +97,7 @@ Code Seq# Include File Comments ...@@ -97,6 +97,7 @@ Code Seq# Include File Comments
<http://linux01.gwdg.de/~alatham/ppdd.html> <http://linux01.gwdg.de/~alatham/ppdd.html>
'M' all linux/soundcard.h 'M' all linux/soundcard.h
'N' 00-1F drivers/usb/scanner.h 'N' 00-1F drivers/usb/scanner.h
'O' 00-02 include/mtd/ubi-user.h UBI
'P' all linux/soundcard.h 'P' all linux/soundcard.h
'Q' all linux/soundcard.h 'Q' all linux/soundcard.h
'R' 00-1F linux/random.h 'R' 00-1F linux/random.h
...@@ -142,6 +143,9 @@ Code Seq# Include File Comments ...@@ -142,6 +143,9 @@ Code Seq# Include File Comments
'n' 00-7F linux/ncp_fs.h 'n' 00-7F linux/ncp_fs.h
'n' E0-FF video/matrox.h matroxfb 'n' E0-FF video/matrox.h matroxfb
'o' 00-1F fs/ocfs2/ocfs2_fs.h OCFS2 'o' 00-1F fs/ocfs2/ocfs2_fs.h OCFS2
'o' 00-03 include/mtd/ubi-user.h conflict! (OCFS2 and UBI overlaps)
'o' 40-41 include/mtd/ubi-user.h UBI
'o' 01-A1 include/linux/dvb/*.h DVB
'p' 00-0F linux/phantom.h conflict! (OpenHaptics needs this) 'p' 00-0F linux/phantom.h conflict! (OpenHaptics needs this)
'p' 00-3F linux/mc146818rtc.h conflict! 'p' 00-3F linux/mc146818rtc.h conflict!
'p' 40-7F linux/nvram.h 'p' 40-7F linux/nvram.h
......
...@@ -815,19 +815,20 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, int vid_hdr_offset) ...@@ -815,19 +815,20 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, int vid_hdr_offset)
if (err) if (err)
goto out_free; goto out_free;
err = -ENOMEM;
ubi->peb_buf1 = vmalloc(ubi->peb_size); ubi->peb_buf1 = vmalloc(ubi->peb_size);
if (!ubi->peb_buf1) if (!ubi->peb_buf1)
goto out_free; goto out_free;
ubi->peb_buf2 = vmalloc(ubi->peb_size); ubi->peb_buf2 = vmalloc(ubi->peb_size);
if (!ubi->peb_buf2) if (!ubi->peb_buf2)
goto out_free; goto out_free;
#ifdef CONFIG_MTD_UBI_DEBUG #ifdef CONFIG_MTD_UBI_DEBUG
mutex_init(&ubi->dbg_buf_mutex); mutex_init(&ubi->dbg_buf_mutex);
ubi->dbg_peb_buf = vmalloc(ubi->peb_size); ubi->dbg_peb_buf = vmalloc(ubi->peb_size);
if (!ubi->dbg_peb_buf) if (!ubi->dbg_peb_buf)
goto out_free; goto out_free;
#endif #endif
err = attach_by_scanning(ubi); err = attach_by_scanning(ubi);
......
...@@ -721,7 +721,8 @@ static int rename_volumes(struct ubi_device *ubi, ...@@ -721,7 +721,8 @@ static int rename_volumes(struct ubi_device *ubi,
* It seems we need to remove volume with name @re->new_name, * It seems we need to remove volume with name @re->new_name,
* if it exists. * if it exists.
*/ */
desc = ubi_open_volume_nm(ubi->ubi_num, re->new_name, UBI_EXCLUSIVE); desc = ubi_open_volume_nm(ubi->ubi_num, re->new_name,
UBI_EXCLUSIVE);
if (IS_ERR(desc)) { if (IS_ERR(desc)) {
err = PTR_ERR(desc); err = PTR_ERR(desc);
if (err == -ENODEV) if (err == -ENODEV)
......
...@@ -27,11 +27,11 @@ ...@@ -27,11 +27,11 @@
#define dbg_err(fmt, ...) ubi_err(fmt, ##__VA_ARGS__) #define dbg_err(fmt, ...) ubi_err(fmt, ##__VA_ARGS__)
#define ubi_assert(expr) do { \ #define ubi_assert(expr) do { \
if (unlikely(!(expr))) { \ if (unlikely(!(expr))) { \
printk(KERN_CRIT "UBI assert failed in %s at %u (pid %d)\n", \ printk(KERN_CRIT "UBI assert failed in %s at %u (pid %d)\n", \
__func__, __LINE__, current->pid); \ __func__, __LINE__, current->pid); \
ubi_dbg_dump_stack(); \ ubi_dbg_dump_stack(); \
} \ } \
} while (0) } while (0)
#define dbg_msg(fmt, ...) \ #define dbg_msg(fmt, ...) \
......
...@@ -504,12 +504,9 @@ static int recover_peb(struct ubi_device *ubi, int pnum, int vol_id, int lnum, ...@@ -504,12 +504,9 @@ static int recover_peb(struct ubi_device *ubi, int pnum, int vol_id, int lnum,
if (!vid_hdr) if (!vid_hdr)
return -ENOMEM; return -ENOMEM;
mutex_lock(&ubi->buf_mutex);
retry: retry:
new_pnum = ubi_wl_get_peb(ubi, UBI_UNKNOWN); new_pnum = ubi_wl_get_peb(ubi, UBI_UNKNOWN);
if (new_pnum < 0) { if (new_pnum < 0) {
mutex_unlock(&ubi->buf_mutex);
ubi_free_vid_hdr(ubi, vid_hdr); ubi_free_vid_hdr(ubi, vid_hdr);
return new_pnum; return new_pnum;
} }
...@@ -529,20 +526,23 @@ retry: ...@@ -529,20 +526,23 @@ retry:
goto write_error; goto write_error;
data_size = offset + len; data_size = offset + len;
mutex_lock(&ubi->buf_mutex);
memset(ubi->peb_buf1 + offset, 0xFF, len); memset(ubi->peb_buf1 + offset, 0xFF, len);
/* Read everything before the area where the write failure happened */ /* Read everything before the area where the write failure happened */
if (offset > 0) { if (offset > 0) {
err = ubi_io_read_data(ubi, ubi->peb_buf1, pnum, 0, offset); err = ubi_io_read_data(ubi, ubi->peb_buf1, pnum, 0, offset);
if (err && err != UBI_IO_BITFLIPS) if (err && err != UBI_IO_BITFLIPS)
goto out_put; goto out_unlock;
} }
memcpy(ubi->peb_buf1 + offset, buf, len); memcpy(ubi->peb_buf1 + offset, buf, len);
err = ubi_io_write_data(ubi, ubi->peb_buf1, new_pnum, 0, data_size); err = ubi_io_write_data(ubi, ubi->peb_buf1, new_pnum, 0, data_size);
if (err) if (err) {
mutex_unlock(&ubi->buf_mutex);
goto write_error; goto write_error;
}
mutex_unlock(&ubi->buf_mutex); mutex_unlock(&ubi->buf_mutex);
ubi_free_vid_hdr(ubi, vid_hdr); ubi_free_vid_hdr(ubi, vid_hdr);
...@@ -553,8 +553,9 @@ retry: ...@@ -553,8 +553,9 @@ retry:
ubi_msg("data was successfully recovered"); ubi_msg("data was successfully recovered");
return 0; return 0;
out_put: out_unlock:
mutex_unlock(&ubi->buf_mutex); mutex_unlock(&ubi->buf_mutex);
out_put:
ubi_wl_put_peb(ubi, new_pnum, 1); ubi_wl_put_peb(ubi, new_pnum, 1);
ubi_free_vid_hdr(ubi, vid_hdr); ubi_free_vid_hdr(ubi, vid_hdr);
return err; return err;
...@@ -567,7 +568,6 @@ write_error: ...@@ -567,7 +568,6 @@ write_error:
ubi_warn("failed to write to PEB %d", new_pnum); 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);
if (++tries > UBI_IO_RETRIES) { if (++tries > UBI_IO_RETRIES) {
mutex_unlock(&ubi->buf_mutex);
ubi_free_vid_hdr(ubi, vid_hdr); ubi_free_vid_hdr(ubi, vid_hdr);
return err; return err;
} }
...@@ -949,10 +949,14 @@ write_error: ...@@ -949,10 +949,14 @@ write_error:
* This function copies logical eraseblock from physical eraseblock @from to * This function copies logical eraseblock from physical eraseblock @from to
* physical eraseblock @to. The @vid_hdr buffer may be changed by this * physical eraseblock @to. The @vid_hdr buffer may be changed by this
* function. Returns: * function. Returns:
* o %0 in case of success; * o %0 in case of success;
* o %1 if the operation was canceled and should be tried later (e.g., * o %1 if the operation was canceled because the volume is being deleted
* because a bit-flip was detected at the target PEB); * or because the PEB was put meanwhile;
* o %2 if the volume is being deleted and this LEB should not be moved. * o %2 if the operation was canceled because there was a write error to the
* target PEB;
* o %-EAGAIN if the operation was canceled because a bit-flip was detected
* in the target PEB;
* o a negative error code in case of failure.
*/ */
int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to, int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to,
struct ubi_vid_hdr *vid_hdr) struct ubi_vid_hdr *vid_hdr)
...@@ -978,7 +982,7 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to, ...@@ -978,7 +982,7 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to,
/* /*
* Note, we may race with volume deletion, which means that the volume * Note, we may race with volume deletion, which means that the volume
* this logical eraseblock belongs to might be being deleted. Since the * this logical eraseblock belongs to might be being deleted. Since the
* volume deletion unmaps all the volume's logical eraseblocks, it will * volume deletion un-maps all the volume's logical eraseblocks, it will
* be locked in 'ubi_wl_put_peb()' and wait for the WL worker to finish. * be locked in 'ubi_wl_put_peb()' and wait for the WL worker to finish.
*/ */
vol = ubi->volumes[idx]; vol = ubi->volumes[idx];
...@@ -986,7 +990,7 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to, ...@@ -986,7 +990,7 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to,
/* No need to do further work, cancel */ /* No need to do further work, cancel */
dbg_eba("volume %d is being removed, cancel", vol_id); dbg_eba("volume %d is being removed, cancel", vol_id);
spin_unlock(&ubi->volumes_lock); spin_unlock(&ubi->volumes_lock);
return 2; return 1;
} }
spin_unlock(&ubi->volumes_lock); spin_unlock(&ubi->volumes_lock);
...@@ -1023,7 +1027,7 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to, ...@@ -1023,7 +1027,7 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to,
/* /*
* OK, now the LEB is locked and we can safely start moving it. Since * OK, now the LEB is locked and we can safely start moving it. Since
* this function utilizes thie @ubi->peb1_buf buffer which is shared * this function utilizes the @ubi->peb1_buf buffer which is shared
* with some other functions, so lock the buffer by taking the * with some other functions, so lock the buffer by taking the
* @ubi->buf_mutex. * @ubi->buf_mutex.
*/ */
...@@ -1068,8 +1072,11 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to, ...@@ -1068,8 +1072,11 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to,
vid_hdr->sqnum = cpu_to_be64(next_sqnum(ubi)); vid_hdr->sqnum = cpu_to_be64(next_sqnum(ubi));
err = ubi_io_write_vid_hdr(ubi, to, vid_hdr); err = ubi_io_write_vid_hdr(ubi, to, vid_hdr);
if (err) if (err) {
if (err == -EIO)
err = 2;
goto out_unlock_buf; goto out_unlock_buf;
}
cond_resched(); cond_resched();
...@@ -1079,14 +1086,17 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to, ...@@ -1079,14 +1086,17 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to,
if (err != UBI_IO_BITFLIPS) if (err != UBI_IO_BITFLIPS)
ubi_warn("cannot read VID header back from PEB %d", to); ubi_warn("cannot read VID header back from PEB %d", to);
else else
err = 1; err = -EAGAIN;
goto out_unlock_buf; goto out_unlock_buf;
} }
if (data_size > 0) { if (data_size > 0) {
err = ubi_io_write_data(ubi, ubi->peb_buf1, to, 0, aldata_size); err = ubi_io_write_data(ubi, ubi->peb_buf1, to, 0, aldata_size);
if (err) if (err) {
if (err == -EIO)
err = 2;
goto out_unlock_buf; goto out_unlock_buf;
}
cond_resched(); cond_resched();
...@@ -1101,15 +1111,16 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to, ...@@ -1101,15 +1111,16 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to,
ubi_warn("cannot read data back from PEB %d", ubi_warn("cannot read data back from PEB %d",
to); to);
else else
err = 1; err = -EAGAIN;
goto out_unlock_buf; goto out_unlock_buf;
} }
cond_resched(); cond_resched();
if (memcmp(ubi->peb_buf1, ubi->peb_buf2, aldata_size)) { if (memcmp(ubi->peb_buf1, ubi->peb_buf2, aldata_size)) {
ubi_warn("read data back from PEB %d - it is different", ubi_warn("read data back from PEB %d and it is "
to); "different", to);
err = -EINVAL;
goto out_unlock_buf; goto out_unlock_buf;
} }
} }
......
...@@ -637,8 +637,6 @@ int ubi_io_read_ec_hdr(struct ubi_device *ubi, int pnum, ...@@ -637,8 +637,6 @@ int ubi_io_read_ec_hdr(struct ubi_device *ubi, int pnum,
dbg_io("read EC header from PEB %d", pnum); dbg_io("read EC header from PEB %d", pnum);
ubi_assert(pnum >= 0 && pnum < ubi->peb_count); ubi_assert(pnum >= 0 && pnum < ubi->peb_count);
if (UBI_IO_DEBUG)
verbose = 1;
err = ubi_io_read(ubi, ec_hdr, pnum, 0, UBI_EC_HDR_SIZE); err = ubi_io_read(ubi, ec_hdr, pnum, 0, UBI_EC_HDR_SIZE);
if (err) { if (err) {
...@@ -685,6 +683,9 @@ int ubi_io_read_ec_hdr(struct ubi_device *ubi, int pnum, ...@@ -685,6 +683,9 @@ int ubi_io_read_ec_hdr(struct ubi_device *ubi, int pnum,
if (verbose) if (verbose)
ubi_warn("no EC header found at PEB %d, " ubi_warn("no EC header found at PEB %d, "
"only 0xFF bytes", pnum); "only 0xFF bytes", pnum);
else if (UBI_IO_DEBUG)
dbg_msg("no EC header found at PEB %d, "
"only 0xFF bytes", pnum);
return UBI_IO_PEB_EMPTY; return UBI_IO_PEB_EMPTY;
} }
...@@ -696,7 +697,9 @@ int ubi_io_read_ec_hdr(struct ubi_device *ubi, int pnum, ...@@ -696,7 +697,9 @@ int ubi_io_read_ec_hdr(struct ubi_device *ubi, int pnum,
ubi_warn("bad magic number at PEB %d: %08x instead of " ubi_warn("bad magic number at PEB %d: %08x instead of "
"%08x", pnum, magic, UBI_EC_HDR_MAGIC); "%08x", pnum, magic, UBI_EC_HDR_MAGIC);
ubi_dbg_dump_ec_hdr(ec_hdr); ubi_dbg_dump_ec_hdr(ec_hdr);
} } else if (UBI_IO_DEBUG)
dbg_msg("bad magic number at PEB %d: %08x instead of "
"%08x", pnum, magic, UBI_EC_HDR_MAGIC);
return UBI_IO_BAD_EC_HDR; return UBI_IO_BAD_EC_HDR;
} }
...@@ -708,7 +711,9 @@ int ubi_io_read_ec_hdr(struct ubi_device *ubi, int pnum, ...@@ -708,7 +711,9 @@ int ubi_io_read_ec_hdr(struct ubi_device *ubi, int pnum,
ubi_warn("bad EC header CRC at PEB %d, calculated " ubi_warn("bad EC header CRC at PEB %d, calculated "
"%#08x, read %#08x", pnum, crc, hdr_crc); "%#08x, read %#08x", pnum, crc, hdr_crc);
ubi_dbg_dump_ec_hdr(ec_hdr); ubi_dbg_dump_ec_hdr(ec_hdr);
} } else if (UBI_IO_DEBUG)
dbg_msg("bad EC header CRC at PEB %d, calculated "
"%#08x, read %#08x", pnum, crc, hdr_crc);
return UBI_IO_BAD_EC_HDR; return UBI_IO_BAD_EC_HDR;
} }
...@@ -912,8 +917,6 @@ int ubi_io_read_vid_hdr(struct ubi_device *ubi, int pnum, ...@@ -912,8 +917,6 @@ int ubi_io_read_vid_hdr(struct ubi_device *ubi, int pnum,
dbg_io("read VID header from PEB %d", pnum); dbg_io("read VID header from PEB %d", pnum);
ubi_assert(pnum >= 0 && pnum < ubi->peb_count); ubi_assert(pnum >= 0 && pnum < ubi->peb_count);
if (UBI_IO_DEBUG)
verbose = 1;
p = (char *)vid_hdr - ubi->vid_hdr_shift; p = (char *)vid_hdr - ubi->vid_hdr_shift;
err = ubi_io_read(ubi, p, pnum, ubi->vid_hdr_aloffset, err = ubi_io_read(ubi, p, pnum, ubi->vid_hdr_aloffset,
...@@ -960,6 +963,9 @@ int ubi_io_read_vid_hdr(struct ubi_device *ubi, int pnum, ...@@ -960,6 +963,9 @@ int ubi_io_read_vid_hdr(struct ubi_device *ubi, int pnum,
if (verbose) if (verbose)
ubi_warn("no VID header found at PEB %d, " ubi_warn("no VID header found at PEB %d, "
"only 0xFF bytes", pnum); "only 0xFF bytes", pnum);
else if (UBI_IO_DEBUG)
dbg_msg("no VID header found at PEB %d, "
"only 0xFF bytes", pnum);
return UBI_IO_PEB_FREE; return UBI_IO_PEB_FREE;
} }
...@@ -971,7 +977,9 @@ int ubi_io_read_vid_hdr(struct ubi_device *ubi, int pnum, ...@@ -971,7 +977,9 @@ int ubi_io_read_vid_hdr(struct ubi_device *ubi, int pnum,
ubi_warn("bad magic number at PEB %d: %08x instead of " ubi_warn("bad magic number at PEB %d: %08x instead of "
"%08x", pnum, magic, UBI_VID_HDR_MAGIC); "%08x", pnum, magic, UBI_VID_HDR_MAGIC);
ubi_dbg_dump_vid_hdr(vid_hdr); ubi_dbg_dump_vid_hdr(vid_hdr);
} } else if (UBI_IO_DEBUG)
dbg_msg("bad magic number at PEB %d: %08x instead of "
"%08x", pnum, magic, UBI_VID_HDR_MAGIC);
return UBI_IO_BAD_VID_HDR; return UBI_IO_BAD_VID_HDR;
} }
...@@ -983,7 +991,9 @@ int ubi_io_read_vid_hdr(struct ubi_device *ubi, int pnum, ...@@ -983,7 +991,9 @@ int ubi_io_read_vid_hdr(struct ubi_device *ubi, int pnum,
ubi_warn("bad CRC at PEB %d, calculated %#08x, " ubi_warn("bad CRC at PEB %d, calculated %#08x, "
"read %#08x", pnum, crc, hdr_crc); "read %#08x", pnum, crc, hdr_crc);
ubi_dbg_dump_vid_hdr(vid_hdr); ubi_dbg_dump_vid_hdr(vid_hdr);
} } else if (UBI_IO_DEBUG)
dbg_msg("bad CRC at PEB %d, calculated %#08x, "
"read %#08x", pnum, crc, hdr_crc);
return UBI_IO_BAD_VID_HDR; return UBI_IO_BAD_VID_HDR;
} }
...@@ -1024,7 +1034,7 @@ int ubi_io_write_vid_hdr(struct ubi_device *ubi, int pnum, ...@@ -1024,7 +1034,7 @@ int ubi_io_write_vid_hdr(struct ubi_device *ubi, int pnum,
err = paranoid_check_peb_ec_hdr(ubi, pnum); err = paranoid_check_peb_ec_hdr(ubi, pnum);
if (err) if (err)
return err > 0 ? -EINVAL: err; return err > 0 ? -EINVAL : err;
vid_hdr->magic = cpu_to_be32(UBI_VID_HDR_MAGIC); vid_hdr->magic = cpu_to_be32(UBI_VID_HDR_MAGIC);
vid_hdr->version = UBI_VERSION; vid_hdr->version = UBI_VERSION;
......
...@@ -73,6 +73,13 @@ ...@@ -73,6 +73,13 @@
*/ */
#define UBI_IO_RETRIES 3 #define UBI_IO_RETRIES 3
/*
* Length of the protection queue. The length is effectively equivalent to the
* number of (global) erase cycles PEBs are protected from the wear-leveling
* worker.
*/
#define UBI_PROT_QUEUE_LEN 10
/* /*
* Error codes returned by the I/O sub-system. * Error codes returned by the I/O sub-system.
* *
...@@ -95,7 +102,8 @@ enum { ...@@ -95,7 +102,8 @@ enum {
/** /**
* struct ubi_wl_entry - wear-leveling entry. * struct ubi_wl_entry - wear-leveling entry.
* @rb: link in the corresponding RB-tree * @u.rb: link in the corresponding (free/used) RB-tree
* @u.list: link in the protection queue
* @ec: erase counter * @ec: erase counter
* @pnum: physical eraseblock number * @pnum: physical eraseblock number
* *
...@@ -104,7 +112,10 @@ enum { ...@@ -104,7 +112,10 @@ enum {
* RB-trees. See WL sub-system for details. * RB-trees. See WL sub-system for details.
*/ */
struct ubi_wl_entry { struct ubi_wl_entry {
struct rb_node rb; union {
struct rb_node rb;
struct list_head list;
} u;
int ec; int ec;
int pnum; int pnum;
}; };
...@@ -288,7 +299,7 @@ struct ubi_wl_entry; ...@@ -288,7 +299,7 @@ struct ubi_wl_entry;
* @beb_rsvd_level: normal level of PEBs reserved for bad PEB handling * @beb_rsvd_level: normal level of PEBs reserved for bad PEB handling
* *
* @autoresize_vol_id: ID of the volume which has to be auto-resized at the end * @autoresize_vol_id: ID of the volume which has to be auto-resized at the end
* of UBI ititializetion * of UBI initialization
* @vtbl_slots: how many slots are available in the volume table * @vtbl_slots: how many slots are available in the volume table
* @vtbl_size: size of the volume table in bytes * @vtbl_size: size of the volume table in bytes
* @vtbl: in-RAM volume table copy * @vtbl: in-RAM volume table copy
...@@ -306,18 +317,17 @@ struct ubi_wl_entry; ...@@ -306,18 +317,17 @@ struct ubi_wl_entry;
* @used: RB-tree of used physical eraseblocks * @used: RB-tree of used physical eraseblocks
* @free: RB-tree of free physical eraseblocks * @free: RB-tree of free physical eraseblocks
* @scrub: RB-tree of physical eraseblocks which need scrubbing * @scrub: RB-tree of physical eraseblocks which need scrubbing
* @prot: protection trees * @pq: protection queue (contain physical eraseblocks which are temporarily
* @prot.pnum: protection tree indexed by physical eraseblock numbers * protected from the wear-leveling worker)
* @prot.aec: protection tree indexed by absolute erase counter value * @pq_head: protection queue head
* @wl_lock: protects the @used, @free, @prot, @lookuptbl, @abs_ec, @move_from, * @wl_lock: protects the @used, @free, @pq, @pq_head, @lookuptbl, @move_from,
* @move_to, @move_to_put @erase_pending, @wl_scheduled, and @works * @move_to, @move_to_put @erase_pending, @wl_scheduled and @works
* fields * fields
* @move_mutex: serializes eraseblock moves * @move_mutex: serializes eraseblock moves
* @work_sem: sycnhronizes the WL worker with use tasks * @work_sem: synchronizes the WL worker with use tasks
* @wl_scheduled: non-zero if the wear-leveling was scheduled * @wl_scheduled: non-zero if the wear-leveling was scheduled
* @lookuptbl: a table to quickly find a &struct ubi_wl_entry object for any * @lookuptbl: a table to quickly find a &struct ubi_wl_entry object for any
* physical eraseblock * physical eraseblock
* @abs_ec: absolute erase counter
* @move_from: physical eraseblock from where the data is being moved * @move_from: physical eraseblock from where the data is being moved
* @move_to: physical eraseblock where the data is being moved to * @move_to: physical eraseblock where the data is being moved to
* @move_to_put: if the "to" PEB was put * @move_to_put: if the "to" PEB was put
...@@ -351,11 +361,11 @@ struct ubi_wl_entry; ...@@ -351,11 +361,11 @@ struct ubi_wl_entry;
* *
* @peb_buf1: a buffer of PEB size used for different purposes * @peb_buf1: a buffer of PEB size used for different purposes
* @peb_buf2: another buffer of PEB size used for different purposes * @peb_buf2: another buffer of PEB size used for different purposes
* @buf_mutex: proptects @peb_buf1 and @peb_buf2 * @buf_mutex: protects @peb_buf1 and @peb_buf2
* @ckvol_mutex: serializes static volume checking when opening * @ckvol_mutex: serializes static volume checking when opening
* @mult_mutex: serializes operations on multiple volumes, like re-nameing * @mult_mutex: serializes operations on multiple volumes, like re-naming
* @dbg_peb_buf: buffer of PEB size used for debugging * @dbg_peb_buf: buffer of PEB size used for debugging
* @dbg_buf_mutex: proptects @dbg_peb_buf * @dbg_buf_mutex: protects @dbg_peb_buf
*/ */
struct ubi_device { struct ubi_device {
struct cdev cdev; struct cdev cdev;
...@@ -392,16 +402,13 @@ struct ubi_device { ...@@ -392,16 +402,13 @@ struct ubi_device {
struct rb_root used; struct rb_root used;
struct rb_root free; struct rb_root free;
struct rb_root scrub; struct rb_root scrub;
struct { struct list_head pq[UBI_PROT_QUEUE_LEN];
struct rb_root pnum; int pq_head;
struct rb_root aec;
} prot;
spinlock_t wl_lock; spinlock_t wl_lock;
struct mutex move_mutex; struct mutex move_mutex;
struct rw_semaphore work_sem; struct rw_semaphore work_sem;
int wl_scheduled; int wl_scheduled;
struct ubi_wl_entry **lookuptbl; struct ubi_wl_entry **lookuptbl;
unsigned long long abs_ec;
struct ubi_wl_entry *move_from; struct ubi_wl_entry *move_from;
struct ubi_wl_entry *move_to; struct ubi_wl_entry *move_to;
int move_to_put; int move_to_put;
......
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment