From ae616e1be13599c3b64e544ebe99e69ea851e99c Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Wed, 16 Jan 2008 12:15:47 +0200 Subject: UBI: fix warnings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit drivers/mtd/ubi/cdev.c: In function ‘vol_cdev_read’: drivers/mtd/ubi/cdev.c:187: warning: unused variable ‘vol_id’ CC [M] drivers/mtd/ubi/kapi.o drivers/mtd/ubi/kapi.c: In function ‘ubi_leb_erase’: drivers/mtd/ubi/kapi.c:483: warning: unused variable ‘vol_id’ drivers/mtd/ubi/kapi.c: In function ‘ubi_leb_unmap’: drivers/mtd/ubi/kapi.c:544: warning: unused variable ‘vol_id’ drivers/mtd/ubi/kapi.c: In function ‘ubi_leb_map’: drivers/mtd/ubi/kapi.c:582: warning: unused variable ‘vol_id’ Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/cdev.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers/mtd/ubi/cdev.c') diff --git a/drivers/mtd/ubi/cdev.c b/drivers/mtd/ubi/cdev.c index a60a3a24c2a..a7aa123afaf 100644 --- a/drivers/mtd/ubi/cdev.c +++ b/drivers/mtd/ubi/cdev.c @@ -184,13 +184,13 @@ static ssize_t vol_cdev_read(struct file *file, __user char *buf, size_t count, struct ubi_volume_desc *desc = file->private_data; struct ubi_volume *vol = desc->vol; struct ubi_device *ubi = vol->ubi; - int err, lnum, off, len, vol_id = desc->vol->vol_id, tbuf_size; + int err, lnum, off, len, tbuf_size; size_t count_save = count; void *tbuf; uint64_t tmp; dbg_msg("read %zd bytes from offset %lld of volume %d", - count, *offp, vol_id); + count, *offp, vol->vol_id); if (vol->updating) { dbg_err("updating"); @@ -204,7 +204,7 @@ static ssize_t vol_cdev_read(struct file *file, __user char *buf, size_t count, return 0; if (vol->corrupted) - dbg_msg("read from corrupted volume %d", vol_id); + dbg_msg("read from corrupted volume %d", vol->vol_id); if (*offp + count > vol->used_bytes) count_save = count = vol->used_bytes - *offp; @@ -268,13 +268,13 @@ static ssize_t vol_cdev_direct_write(struct file *file, const char __user *buf, struct ubi_volume_desc *desc = file->private_data; struct ubi_volume *vol = desc->vol; struct ubi_device *ubi = vol->ubi; - int lnum, off, len, tbuf_size, vol_id = vol->vol_id, err = 0; + int lnum, off, len, tbuf_size, err = 0; size_t count_save = count; char *tbuf; uint64_t tmp; dbg_msg("requested: write %zd bytes to offset %lld of volume %u", - count, *offp, desc->vol->vol_id); + count, *offp, vol->vol_id); if (vol->vol_type == UBI_STATIC_VOLUME) return -EROFS; -- cgit v1.2.3 From 0411e7353192d7deebd4f50b9ee41974ec3a634c Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Thu, 24 Jan 2008 16:45:57 +0200 Subject: UBI: do not change file pointer while updating Since we do not change semantics of seek(), changing the file pointer while updating does not make much sense. Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/cdev.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers/mtd/ubi/cdev.c') diff --git a/drivers/mtd/ubi/cdev.c b/drivers/mtd/ubi/cdev.c index a7aa123afaf..d9bd49421cc 100644 --- a/drivers/mtd/ubi/cdev.c +++ b/drivers/mtd/ubi/cdev.c @@ -368,6 +368,7 @@ static ssize_t vol_cdev_write(struct file *file, const char __user *buf, */ count = err; + vol->updating = 0; err = ubi_check_volume(ubi, vol->vol_id); if (err < 0) return err; @@ -382,7 +383,6 @@ static ssize_t vol_cdev_write(struct file *file, const char __user *buf, revoke_exclusive(desc, UBI_READWRITE); } - *offp += count; return count; } @@ -430,8 +430,6 @@ static int vol_cdev_ioctl(struct inode *inode, struct file *file, err = ubi_start_update(ubi, vol->vol_id, bytes); if (bytes == 0) revoke_exclusive(desc, UBI_READWRITE); - - file->f_pos = 0; break; } -- cgit v1.2.3 From 1b68d0eea5daddc762c54bf02154f4ad607d9ce8 Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Thu, 24 Jan 2008 17:04:01 +0200 Subject: UBI: simplify internal interfaces Instead of passing vol_id to all functions and then find struct ubi_volume, pass struct ubi_volume pointer. Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/cdev.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/mtd/ubi/cdev.c') diff --git a/drivers/mtd/ubi/cdev.c b/drivers/mtd/ubi/cdev.c index d9bd49421cc..0c4044d6cae 100644 --- a/drivers/mtd/ubi/cdev.c +++ b/drivers/mtd/ubi/cdev.c @@ -354,7 +354,7 @@ static ssize_t vol_cdev_write(struct file *file, const char __user *buf, if (!vol->updating) return vol_cdev_direct_write(file, buf, count, offp); - err = ubi_more_update_data(ubi, vol->vol_id, buf, count); + err = ubi_more_update_data(ubi, vol, buf, count); if (err < 0) { ubi_err("cannot write %zd bytes of update data, error %d", count, err); @@ -427,7 +427,7 @@ static int vol_cdev_ioctl(struct inode *inode, struct file *file, if (err < 0) break; - err = ubi_start_update(ubi, vol->vol_id, bytes); + err = ubi_start_update(ubi, vol, bytes); if (bytes == 0) revoke_exclusive(desc, UBI_READWRITE); break; -- cgit v1.2.3 From e653879c269735c9ff6684e03edf1d4e041ff3d3 Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Thu, 24 Jan 2008 18:48:21 +0200 Subject: UBI: implement atomic LEB change ioctl Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/cdev.c | 72 +++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 60 insertions(+), 12 deletions(-) (limited to 'drivers/mtd/ubi/cdev.c') diff --git a/drivers/mtd/ubi/cdev.c b/drivers/mtd/ubi/cdev.c index 0c4044d6cae..9d6aae5449b 100644 --- a/drivers/mtd/ubi/cdev.c +++ b/drivers/mtd/ubi/cdev.c @@ -132,8 +132,15 @@ static int vol_cdev_release(struct inode *inode, struct file *file) if (vol->updating) { ubi_warn("update of volume %d not finished, volume is damaged", vol->vol_id); + ubi_assert(!vol->changing_leb); vol->updating = 0; vfree(vol->upd_buf); + } else if (vol->changing_leb) { + dbg_msg("only %lld of %lld bytes received for atomic LEB change" + " for volume %d:%d, cancel", vol->upd_received, + vol->upd_bytes, vol->ubi->ubi_num, vol->vol_id); + vol->changing_leb = 0; + vfree(vol->upd_buf); } ubi_close_volume(desc); @@ -351,24 +358,32 @@ static ssize_t vol_cdev_write(struct file *file, const char __user *buf, struct ubi_volume *vol = desc->vol; struct ubi_device *ubi = vol->ubi; - if (!vol->updating) + if (!vol->updating && !vol->changing_leb) return vol_cdev_direct_write(file, buf, count, offp); - err = ubi_more_update_data(ubi, vol, buf, count); + if (vol->updating) + err = ubi_more_update_data(ubi, vol, buf, count); + else + err = ubi_more_leb_change_data(ubi, vol, buf, count); + if (err < 0) { - ubi_err("cannot write %zd bytes of update data, error %d", + ubi_err("cannot accept more %zd bytes of data, error %d", count, err); return err; } if (err) { /* - * Update is finished, @err contains number of actually written - * bytes now. + * The operation is finished, @err contains number of actually + * written bytes. */ count = err; - vol->updating = 0; + if (vol->changing_leb) { + revoke_exclusive(desc, UBI_READWRITE); + return count; + } + err = ubi_check_volume(ubi, vol->vol_id); if (err < 0) return err; @@ -433,6 +448,43 @@ static int vol_cdev_ioctl(struct inode *inode, struct file *file, break; } + /* Atomic logical eraseblock change command */ + case UBI_IOCEBCH: + { + struct ubi_leb_change_req req; + + err = copy_from_user(&req, argp, + sizeof(struct ubi_leb_change_req)); + if (err) { + err = -EFAULT; + break; + } + + if (desc->mode == UBI_READONLY || + vol->vol_type == UBI_STATIC_VOLUME) { + err = -EROFS; + break; + } + + /* Validate the request */ + err = -EINVAL; + if (req.lnum < 0 || req.lnum >= vol->reserved_pebs || + req.bytes < 0 || req.lnum >= vol->usable_leb_size) + break; + if (req.dtype != UBI_LONGTERM && req.dtype != UBI_SHORTTERM && + req.dtype != UBI_UNKNOWN) + break; + + err = get_exclusive(desc); + if (err < 0) + break; + + err = ubi_start_leb_change(ubi, vol, &req); + if (req.bytes == 0) + revoke_exclusive(desc, UBI_READWRITE); + break; + } + #ifdef CONFIG_MTD_UBI_DEBUG_USERSPACE_IO /* Logical eraseblock erasure command */ case UBI_IOCEBER: @@ -445,7 +497,8 @@ static int vol_cdev_ioctl(struct inode *inode, struct file *file, break; } - if (desc->mode == UBI_READONLY) { + if (desc->mode == UBI_READONLY || + vol->vol_type == UBI_STATIC_VOLUME) { err = -EROFS; break; } @@ -455,11 +508,6 @@ static int vol_cdev_ioctl(struct inode *inode, struct file *file, break; } - if (vol->vol_type != UBI_DYNAMIC_VOLUME) { - err = -EROFS; - break; - } - dbg_msg("erase LEB %d:%d", vol->vol_id, lnum); err = ubi_eba_unmap_leb(ubi, vol, lnum); if (err) -- cgit v1.2.3