|
@@ -949,10 +949,14 @@ write_error:
|
|
|
* This function copies logical eraseblock from physical eraseblock @from to
|
|
|
* physical eraseblock @to. The @vid_hdr buffer may be changed by this
|
|
|
* function. Returns:
|
|
|
- * o %0 in case of success;
|
|
|
- * o %1 if the operation was canceled and should be tried later (e.g.,
|
|
|
- * because a bit-flip was detected at the target PEB);
|
|
|
- * o %2 if the volume is being deleted and this LEB should not be moved.
|
|
|
+ * o %0 in case of success;
|
|
|
+ * o %1 if the operation was canceled because the volume is being deleted
|
|
|
+ * or because the PEB was put meanwhile;
|
|
|
+ * 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,
|
|
|
struct ubi_vid_hdr *vid_hdr)
|
|
@@ -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
|
|
|
* 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.
|
|
|
*/
|
|
|
vol = ubi->volumes[idx];
|
|
@@ -986,7 +990,7 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to,
|
|
|
/* No need to do further work, cancel */
|
|
|
dbg_eba("volume %d is being removed, cancel", vol_id);
|
|
|
spin_unlock(&ubi->volumes_lock);
|
|
|
- return 2;
|
|
|
+ return 1;
|
|
|
}
|
|
|
spin_unlock(&ubi->volumes_lock);
|
|
|
|
|
@@ -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
|
|
|
- * 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
|
|
|
* @ubi->buf_mutex.
|
|
|
*/
|
|
@@ -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));
|
|
|
|
|
|
err = ubi_io_write_vid_hdr(ubi, to, vid_hdr);
|
|
|
- if (err)
|
|
|
+ if (err) {
|
|
|
+ if (err == -EIO)
|
|
|
+ err = 2;
|
|
|
goto out_unlock_buf;
|
|
|
+ }
|
|
|
|
|
|
cond_resched();
|
|
|
|
|
@@ -1079,14 +1086,17 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to,
|
|
|
if (err != UBI_IO_BITFLIPS)
|
|
|
ubi_warn("cannot read VID header back from PEB %d", to);
|
|
|
else
|
|
|
- err = 1;
|
|
|
+ err = -EAGAIN;
|
|
|
goto out_unlock_buf;
|
|
|
}
|
|
|
|
|
|
if (data_size > 0) {
|
|
|
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;
|
|
|
+ }
|
|
|
|
|
|
cond_resched();
|
|
|
|
|
@@ -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",
|
|
|
to);
|
|
|
else
|
|
|
- err = 1;
|
|
|
+ err = -EAGAIN;
|
|
|
goto out_unlock_buf;
|
|
|
}
|
|
|
|
|
|
cond_resched();
|
|
|
|
|
|
if (memcmp(ubi->peb_buf1, ubi->peb_buf2, aldata_size)) {
|
|
|
- ubi_warn("read data back from PEB %d - it is different",
|
|
|
- to);
|
|
|
+ ubi_warn("read data back from PEB %d and it is "
|
|
|
+ "different", to);
|
|
|
+ err = -EINVAL;
|
|
|
goto out_unlock_buf;
|
|
|
}
|
|
|
}
|