Skip to content

Commit

Permalink
Merge branch 'linux-next' of git://git.infradead.org/~dedekind/ubi-2.6
Browse files Browse the repository at this point in the history
* '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
  • Loading branch information
Linus Torvalds committed Jan 2, 2009
2 parents 56635f7 + f2863c5 commit 574c3fd
Show file tree
Hide file tree
Showing 8 changed files with 305 additions and 330 deletions.
4 changes: 4 additions & 0 deletions Documentation/ioctl/ioctl-number.txt
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ Code Seq# Include File Comments
<http://linux01.gwdg.de/~alatham/ppdd.html>
'M' all linux/soundcard.h
'N' 00-1F drivers/usb/scanner.h
'O' 00-02 include/mtd/ubi-user.h UBI
'P' all linux/soundcard.h
'Q' all linux/soundcard.h
'R' 00-1F linux/random.h
Expand Down Expand Up @@ -142,6 +143,9 @@ Code Seq# Include File Comments
'n' 00-7F linux/ncp_fs.h
'n' E0-FF video/matrox.h matroxfb
'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-3F linux/mc146818rtc.h conflict!
'p' 40-7F linux/nvram.h
Expand Down
5 changes: 3 additions & 2 deletions drivers/mtd/ubi/build.c
Original file line number Diff line number Diff line change
Expand Up @@ -815,19 +815,20 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, int vid_hdr_offset)
if (err)
goto out_free;

err = -ENOMEM;
ubi->peb_buf1 = vmalloc(ubi->peb_size);
if (!ubi->peb_buf1)
goto out_free;

ubi->peb_buf2 = vmalloc(ubi->peb_size);
if (!ubi->peb_buf2)
goto out_free;
goto out_free;

#ifdef CONFIG_MTD_UBI_DEBUG
mutex_init(&ubi->dbg_buf_mutex);
ubi->dbg_peb_buf = vmalloc(ubi->peb_size);
if (!ubi->dbg_peb_buf)
goto out_free;
goto out_free;
#endif

err = attach_by_scanning(ubi);
Expand Down
3 changes: 2 additions & 1 deletion drivers/mtd/ubi/cdev.c
Original file line number Diff line number Diff line change
Expand Up @@ -721,7 +721,8 @@ static int rename_volumes(struct ubi_device *ubi,
* It seems we need to remove volume with name @re->new_name,
* 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)) {
err = PTR_ERR(desc);
if (err == -ENODEV)
Expand Down
10 changes: 5 additions & 5 deletions drivers/mtd/ubi/debug.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,11 @@
#define dbg_err(fmt, ...) ubi_err(fmt, ##__VA_ARGS__)

#define ubi_assert(expr) do { \
if (unlikely(!(expr))) { \
printk(KERN_CRIT "UBI assert failed in %s at %u (pid %d)\n", \
__func__, __LINE__, current->pid); \
ubi_dbg_dump_stack(); \
} \
if (unlikely(!(expr))) { \
printk(KERN_CRIT "UBI assert failed in %s at %u (pid %d)\n", \
__func__, __LINE__, current->pid); \
ubi_dbg_dump_stack(); \
} \
} while (0)

#define dbg_msg(fmt, ...) \
Expand Down
51 changes: 31 additions & 20 deletions drivers/mtd/ubi/eba.c
Original file line number Diff line number Diff line change
Expand Up @@ -504,12 +504,9 @@ static int recover_peb(struct ubi_device *ubi, int pnum, int vol_id, int lnum,
if (!vid_hdr)
return -ENOMEM;

mutex_lock(&ubi->buf_mutex);

retry:
new_pnum = ubi_wl_get_peb(ubi, UBI_UNKNOWN);
if (new_pnum < 0) {
mutex_unlock(&ubi->buf_mutex);
ubi_free_vid_hdr(ubi, vid_hdr);
return new_pnum;
}
Expand All @@ -529,20 +526,23 @@ static int recover_peb(struct ubi_device *ubi, int pnum, int vol_id, int lnum,
goto write_error;

data_size = offset + len;
mutex_lock(&ubi->buf_mutex);
memset(ubi->peb_buf1 + offset, 0xFF, len);

/* Read everything before the area where the write failure happened */
if (offset > 0) {
err = ubi_io_read_data(ubi, ubi->peb_buf1, pnum, 0, offset);
if (err && err != UBI_IO_BITFLIPS)
goto out_put;
goto out_unlock;
}

memcpy(ubi->peb_buf1 + offset, buf, len);

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;
}

mutex_unlock(&ubi->buf_mutex);
ubi_free_vid_hdr(ubi, vid_hdr);
Expand All @@ -553,8 +553,9 @@ static int recover_peb(struct ubi_device *ubi, int pnum, int vol_id, int lnum,
ubi_msg("data was successfully recovered");
return 0;

out_put:
out_unlock:
mutex_unlock(&ubi->buf_mutex);
out_put:
ubi_wl_put_peb(ubi, new_pnum, 1);
ubi_free_vid_hdr(ubi, vid_hdr);
return err;
Expand All @@ -567,7 +568,6 @@ static int recover_peb(struct ubi_device *ubi, int pnum, int vol_id, int lnum,
ubi_warn("failed to write to PEB %d", new_pnum);
ubi_wl_put_peb(ubi, new_pnum, 1);
if (++tries > UBI_IO_RETRIES) {
mutex_unlock(&ubi->buf_mutex);
ubi_free_vid_hdr(ubi, vid_hdr);
return err;
}
Expand Down Expand Up @@ -949,10 +949,14 @@ int ubi_eba_atomic_leb_change(struct ubi_device *ubi, struct ubi_volume *vol,
* 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)
Expand All @@ -978,15 +982,15 @@ 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];
if (!vol) {
/* 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);

Expand Down Expand Up @@ -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.
*/
Expand Down Expand Up @@ -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();

Expand All @@ -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();

Expand All @@ -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;
}
}
Expand Down
28 changes: 19 additions & 9 deletions drivers/mtd/ubi/io.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
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);
if (err) {
Expand Down Expand Up @@ -685,6 +683,9 @@ int ubi_io_read_ec_hdr(struct ubi_device *ubi, int pnum,
if (verbose)
ubi_warn("no EC header found at PEB %d, "
"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;
}

Expand All @@ -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 "
"%08x", pnum, magic, UBI_EC_HDR_MAGIC);
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;
}

Expand All @@ -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 "
"%#08x, read %#08x", pnum, crc, hdr_crc);
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;
}

Expand Down Expand Up @@ -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);
ubi_assert(pnum >= 0 && pnum < ubi->peb_count);
if (UBI_IO_DEBUG)
verbose = 1;

p = (char *)vid_hdr - ubi->vid_hdr_shift;
err = ubi_io_read(ubi, p, pnum, ubi->vid_hdr_aloffset,
Expand Down Expand Up @@ -960,6 +963,9 @@ int ubi_io_read_vid_hdr(struct ubi_device *ubi, int pnum,
if (verbose)
ubi_warn("no VID header found at PEB %d, "
"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;
}

Expand All @@ -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 "
"%08x", pnum, magic, UBI_VID_HDR_MAGIC);
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;
}

Expand All @@ -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, "
"read %#08x", pnum, crc, hdr_crc);
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;
}

Expand Down Expand Up @@ -1024,7 +1034,7 @@ int ubi_io_write_vid_hdr(struct ubi_device *ubi, int pnum,

err = paranoid_check_peb_ec_hdr(ubi, pnum);
if (err)
return err > 0 ? -EINVAL: err;
return err > 0 ? -EINVAL : err;

vid_hdr->magic = cpu_to_be32(UBI_VID_HDR_MAGIC);
vid_hdr->version = UBI_VERSION;
Expand Down
Loading

0 comments on commit 574c3fd

Please sign in to comment.