Loading drivers/mtd/ubi/build.c +68 −35 Original line number Diff line number Diff line Loading @@ -66,9 +66,6 @@ static struct mtd_dev_param mtd_dev_param[UBI_MAX_DEVICES]; /* Root UBI "class" object (corresponds to '/<sysfs>/class/ubi/') */ struct class *ubi_class; /* Slab cache for lock-tree entries */ struct kmem_cache *ubi_ltree_slab; /* Slab cache for wear-leveling entries */ struct kmem_cache *ubi_wl_entry_slab; Loading Loading @@ -369,9 +366,6 @@ static int uif_init(struct ubi_device *ubi) int i, err; dev_t dev; mutex_init(&ubi->volumes_mutex); spin_lock_init(&ubi->volumes_lock); sprintf(ubi->ubi_name, UBI_NAME_STR "%d", ubi->ubi_num); /* Loading Loading @@ -568,7 +562,7 @@ static int io_init(struct ubi_device *ubi) } /* Similar for the data offset */ ubi->leb_start = ubi->vid_hdr_offset + ubi->vid_hdr_alsize; ubi->leb_start = ubi->vid_hdr_offset + UBI_EC_HDR_SIZE; ubi->leb_start = ALIGN(ubi->leb_start, ubi->min_io_size); dbg_msg("vid_hdr_offset %d", ubi->vid_hdr_offset); Loading Loading @@ -626,6 +620,58 @@ static int io_init(struct ubi_device *ubi) return 0; } /** * autoresize - re-size the volume which has the "auto-resize" flag set. * @ubi: UBI device description object * @vol_id: ID of the volume to re-size * * This function re-sizes the volume marked by the @UBI_VTBL_AUTORESIZE_FLG in * the volume table to the largest possible size. See comments in ubi-header.h * for more description of the flag. Returns zero in case of success and a * negative error code in case of failure. */ static int autoresize(struct ubi_device *ubi, int vol_id) { struct ubi_volume_desc desc; struct ubi_volume *vol = ubi->volumes[vol_id]; int err, old_reserved_pebs = vol->reserved_pebs; /* * Clear the auto-resize flag in the volume in-memory copy of the * volume table, and 'ubi_resize_volume()' will propogate this change * to the flash. */ ubi->vtbl[vol_id].flags &= ~UBI_VTBL_AUTORESIZE_FLG; if (ubi->avail_pebs == 0) { struct ubi_vtbl_record vtbl_rec; /* * No avalilable PEBs to re-size the volume, clear the flag on * flash and exit. */ memcpy(&vtbl_rec, &ubi->vtbl[vol_id], sizeof(struct ubi_vtbl_record)); err = ubi_change_vtbl_record(ubi, vol_id, &vtbl_rec); if (err) ubi_err("cannot clean auto-resize flag for volume %d", vol_id); } else { desc.vol = vol; err = ubi_resize_volume(&desc, old_reserved_pebs + ubi->avail_pebs); if (err) ubi_err("cannot auto-resize volume %d", vol_id); } if (err) return err; ubi_msg("volume %d (\"%s\") re-sized from %d to %d LEBs", vol_id, vol->name, old_reserved_pebs, vol->reserved_pebs); return 0; } /** * ubi_attach_mtd_dev - attach an MTD device. * @mtd_dev: MTD device description object Loading Loading @@ -702,6 +748,12 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, int vid_hdr_offset) ubi->mtd = mtd; ubi->ubi_num = ubi_num; ubi->vid_hdr_offset = vid_hdr_offset; ubi->autoresize_vol_id = -1; mutex_init(&ubi->buf_mutex); mutex_init(&ubi->ckvol_mutex); mutex_init(&ubi->volumes_mutex); spin_lock_init(&ubi->volumes_lock); dbg_msg("attaching mtd%d to ubi%d: VID header offset %d", mtd->index, ubi_num, vid_hdr_offset); Loading @@ -710,8 +762,6 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, int vid_hdr_offset) if (err) goto out_free; mutex_init(&ubi->buf_mutex); mutex_init(&ubi->ckvol_mutex); ubi->peb_buf1 = vmalloc(ubi->peb_size); if (!ubi->peb_buf1) goto out_free; Loading @@ -733,6 +783,12 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, int vid_hdr_offset) goto out_free; } if (ubi->autoresize_vol_id != -1) { err = autoresize(ubi, ubi->autoresize_vol_id); if (err) goto out_detach; } err = uif_init(ubi); if (err) goto out_detach; Loading Loading @@ -857,20 +913,6 @@ int ubi_detach_mtd_dev(int ubi_num, int anyway) return 0; } /** * ltree_entry_ctor - lock tree entries slab cache constructor. * @obj: the lock-tree entry to construct * @cache: the lock tree entry slab cache * @flags: constructor flags */ static void ltree_entry_ctor(struct kmem_cache *cache, void *obj) { struct ubi_ltree_entry *le = obj; le->users = 0; init_rwsem(&le->mutex); } /** * find_mtd_device - open an MTD device by its name or number. * @mtd_dev: name or number of the device Loading Loading @@ -933,17 +975,11 @@ static int __init ubi_init(void) goto out_version; } ubi_ltree_slab = kmem_cache_create("ubi_ltree_slab", sizeof(struct ubi_ltree_entry), 0, 0, <ree_entry_ctor); if (!ubi_ltree_slab) goto out_dev_unreg; ubi_wl_entry_slab = kmem_cache_create("ubi_wl_entry_slab", sizeof(struct ubi_wl_entry), 0, 0, NULL); if (!ubi_wl_entry_slab) goto out_ltree; goto out_dev_unreg; /* Attach MTD devices */ for (i = 0; i < mtd_devs; i++) { Loading Loading @@ -980,8 +1016,6 @@ out_detach: mutex_unlock(&ubi_devices_mutex); } kmem_cache_destroy(ubi_wl_entry_slab); out_ltree: kmem_cache_destroy(ubi_ltree_slab); out_dev_unreg: misc_deregister(&ubi_ctrl_cdev); out_version: Loading @@ -1005,7 +1039,6 @@ static void __exit ubi_exit(void) mutex_unlock(&ubi_devices_mutex); } kmem_cache_destroy(ubi_wl_entry_slab); kmem_cache_destroy(ubi_ltree_slab); misc_deregister(&ubi_ctrl_cdev); class_remove_file(ubi_class, &ubi_version); class_destroy(ubi_class); Loading Loading @@ -1066,7 +1099,7 @@ static int __init ubi_mtd_param_parse(const char *val, struct kernel_param *kp) struct mtd_dev_param *p; char buf[MTD_PARAM_LEN_MAX]; char *pbuf = &buf[0]; char *tokens[3] = {NULL, NULL, NULL}; char *tokens[2] = {NULL, NULL}; if (!val) return -EINVAL; Loading Loading @@ -1096,7 +1129,7 @@ static int __init ubi_mtd_param_parse(const char *val, struct kernel_param *kp) if (buf[len - 1] == '\n') buf[len - 1] = '\0'; for (i = 0; i < 3; i++) for (i = 0; i < 2; i++) tokens[i] = strsep(&pbuf, ","); if (pbuf) { Loading drivers/mtd/ubi/cdev.c +64 −18 Original line number Diff line number Diff line Loading @@ -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); Loading Loading @@ -184,13 +191,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"); Loading @@ -204,7 +211,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; Loading Loading @@ -274,7 +281,7 @@ static ssize_t vol_cdev_direct_write(struct file *file, const char __user *buf, 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; Loading Loading @@ -351,23 +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->vol_id, 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; if (vol->changing_leb) { revoke_exclusive(desc, UBI_READWRITE); return count; } err = ubi_check_volume(ubi, vol->vol_id); if (err < 0) return err; Loading @@ -382,7 +398,6 @@ static ssize_t vol_cdev_write(struct file *file, const char __user *buf, revoke_exclusive(desc, UBI_READWRITE); } *offp += count; return count; } Loading Loading @@ -427,11 +442,46 @@ 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; } /* 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; } file->f_pos = 0; /* 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; } Loading @@ -447,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; } Loading @@ -457,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) Loading drivers/mtd/ubi/eba.c +19 −21 Original line number Diff line number Diff line Loading @@ -78,7 +78,7 @@ static unsigned long long next_sqnum(struct ubi_device *ubi) */ static int ubi_get_compat(const struct ubi_device *ubi, int vol_id) { if (vol_id == UBI_LAYOUT_VOL_ID) if (vol_id == UBI_LAYOUT_VOLUME_ID) return UBI_LAYOUT_VOLUME_COMPAT; return 0; } Loading Loading @@ -137,10 +137,12 @@ static struct ubi_ltree_entry *ltree_add_entry(struct ubi_device *ubi, { struct ubi_ltree_entry *le, *le1, *le_free; le = kmem_cache_alloc(ubi_ltree_slab, GFP_NOFS); le = kmalloc(sizeof(struct ubi_ltree_entry), GFP_NOFS); if (!le) return ERR_PTR(-ENOMEM); le->users = 0; init_rwsem(&le->mutex); le->vol_id = vol_id; le->lnum = lnum; Loading Loading @@ -188,7 +190,7 @@ static struct ubi_ltree_entry *ltree_add_entry(struct ubi_device *ubi, spin_unlock(&ubi->ltree_lock); if (le_free) kmem_cache_free(ubi_ltree_slab, le_free); kfree(le_free); return le; } Loading Loading @@ -236,7 +238,7 @@ static void leb_read_unlock(struct ubi_device *ubi, int vol_id, int lnum) up_read(&le->mutex); if (free) kmem_cache_free(ubi_ltree_slab, le); kfree(le); } /** Loading Loading @@ -292,7 +294,7 @@ static int leb_write_trylock(struct ubi_device *ubi, int vol_id, int lnum) free = 0; spin_unlock(&ubi->ltree_lock); if (free) kmem_cache_free(ubi_ltree_slab, le); kfree(le); return 1; } Loading Loading @@ -321,7 +323,7 @@ static void leb_write_unlock(struct ubi_device *ubi, int vol_id, int lnum) up_write(&le->mutex); if (free) kmem_cache_free(ubi_ltree_slab, le); kfree(le); } /** Loading @@ -339,9 +341,6 @@ int ubi_eba_unmap_leb(struct ubi_device *ubi, struct ubi_volume *vol, { int err, pnum, vol_id = vol->vol_id; ubi_assert(ubi->ref_count > 0); ubi_assert(vol->ref_count > 0); if (ubi->ro_mode) return -EROFS; Loading Loading @@ -390,9 +389,6 @@ int ubi_eba_read_leb(struct ubi_device *ubi, struct ubi_volume *vol, int lnum, struct ubi_vid_hdr *vid_hdr; uint32_t uninitialized_var(crc); ubi_assert(ubi->ref_count > 0); ubi_assert(vol->ref_count > 0); err = leb_read_lock(ubi, vol_id, lnum); if (err) return err; Loading Loading @@ -616,9 +612,6 @@ int ubi_eba_write_leb(struct ubi_device *ubi, struct ubi_volume *vol, int lnum, int err, pnum, tries = 0, vol_id = vol->vol_id; struct ubi_vid_hdr *vid_hdr; ubi_assert(ubi->ref_count > 0); ubi_assert(vol->ref_count > 0); if (ubi->ro_mode) return -EROFS; Loading Loading @@ -752,9 +745,6 @@ int ubi_eba_write_leb_st(struct ubi_device *ubi, struct ubi_volume *vol, struct ubi_vid_hdr *vid_hdr; uint32_t crc; ubi_assert(ubi->ref_count > 0); ubi_assert(vol->ref_count > 0); if (ubi->ro_mode) return -EROFS; Loading Loading @@ -869,12 +859,20 @@ int ubi_eba_atomic_leb_change(struct ubi_device *ubi, struct ubi_volume *vol, struct ubi_vid_hdr *vid_hdr; uint32_t crc; ubi_assert(ubi->ref_count > 0); ubi_assert(vol->ref_count > 0); if (ubi->ro_mode) return -EROFS; if (len == 0) { /* * Special case when data length is zero. In this case the LEB * has to be unmapped and mapped somewhere else. */ err = ubi_eba_unmap_leb(ubi, vol, lnum); if (err) return err; return ubi_eba_write_leb(ubi, vol, lnum, NULL, 0, 0, dtype); } vid_hdr = ubi_zalloc_vid_hdr(ubi, GFP_NOFS); if (!vid_hdr) return -ENOMEM; Loading drivers/mtd/ubi/kapi.c +4 −6 Original line number Diff line number Diff line Loading @@ -480,9 +480,9 @@ int ubi_leb_erase(struct ubi_volume_desc *desc, int lnum) { struct ubi_volume *vol = desc->vol; struct ubi_device *ubi = vol->ubi; int err, vol_id = vol->vol_id; int err; dbg_msg("erase LEB %d:%d", vol_id, lnum); dbg_msg("erase LEB %d:%d", vol->vol_id, lnum); if (desc->mode == UBI_READONLY || vol->vol_type == UBI_STATIC_VOLUME) return -EROFS; Loading Loading @@ -541,9 +541,8 @@ int ubi_leb_unmap(struct ubi_volume_desc *desc, int lnum) { 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); dbg_msg("unmap LEB %d:%d", vol->vol_id, lnum); if (desc->mode == UBI_READONLY || vol->vol_type == UBI_STATIC_VOLUME) return -EROFS; Loading Loading @@ -579,9 +578,8 @@ 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); dbg_msg("unmap LEB %d:%d", vol->vol_id, lnum); if (desc->mode == UBI_READONLY || vol->vol_type == UBI_STATIC_VOLUME) return -EROFS; Loading drivers/mtd/ubi/scan.c +7 −3 Original line number Diff line number Diff line Loading @@ -286,9 +286,14 @@ static int compare_lebs(struct ubi_device *ubi, const struct ubi_scan_leb *seb, * FIXME: but this is anyway obsolete and will be removed at * some point. */ dbg_bld("using old crappy leb_ver stuff"); if (v1 == v2) { ubi_err("PEB %d and PEB %d have the same version %lld", seb->pnum, pnum, v1); return -EINVAL; } abs = v1 - v2; if (abs < 0) abs = -abs; Loading Loading @@ -390,7 +395,6 @@ out_free_buf: vfree(buf); out_free_vidh: ubi_free_vid_hdr(ubi, vh); ubi_assert(err < 0); return err; } Loading Loading @@ -854,7 +858,7 @@ static int process_eb(struct ubi_device *ubi, struct ubi_scan_info *si, int pnum } vol_id = be32_to_cpu(vidh->vol_id); if (vol_id > UBI_MAX_VOLUMES && vol_id != UBI_LAYOUT_VOL_ID) { if (vol_id > UBI_MAX_VOLUMES && vol_id != UBI_LAYOUT_VOLUME_ID) { int lnum = be32_to_cpu(vidh->lnum); /* Unsupported internal volume */ Loading Loading
drivers/mtd/ubi/build.c +68 −35 Original line number Diff line number Diff line Loading @@ -66,9 +66,6 @@ static struct mtd_dev_param mtd_dev_param[UBI_MAX_DEVICES]; /* Root UBI "class" object (corresponds to '/<sysfs>/class/ubi/') */ struct class *ubi_class; /* Slab cache for lock-tree entries */ struct kmem_cache *ubi_ltree_slab; /* Slab cache for wear-leveling entries */ struct kmem_cache *ubi_wl_entry_slab; Loading Loading @@ -369,9 +366,6 @@ static int uif_init(struct ubi_device *ubi) int i, err; dev_t dev; mutex_init(&ubi->volumes_mutex); spin_lock_init(&ubi->volumes_lock); sprintf(ubi->ubi_name, UBI_NAME_STR "%d", ubi->ubi_num); /* Loading Loading @@ -568,7 +562,7 @@ static int io_init(struct ubi_device *ubi) } /* Similar for the data offset */ ubi->leb_start = ubi->vid_hdr_offset + ubi->vid_hdr_alsize; ubi->leb_start = ubi->vid_hdr_offset + UBI_EC_HDR_SIZE; ubi->leb_start = ALIGN(ubi->leb_start, ubi->min_io_size); dbg_msg("vid_hdr_offset %d", ubi->vid_hdr_offset); Loading Loading @@ -626,6 +620,58 @@ static int io_init(struct ubi_device *ubi) return 0; } /** * autoresize - re-size the volume which has the "auto-resize" flag set. * @ubi: UBI device description object * @vol_id: ID of the volume to re-size * * This function re-sizes the volume marked by the @UBI_VTBL_AUTORESIZE_FLG in * the volume table to the largest possible size. See comments in ubi-header.h * for more description of the flag. Returns zero in case of success and a * negative error code in case of failure. */ static int autoresize(struct ubi_device *ubi, int vol_id) { struct ubi_volume_desc desc; struct ubi_volume *vol = ubi->volumes[vol_id]; int err, old_reserved_pebs = vol->reserved_pebs; /* * Clear the auto-resize flag in the volume in-memory copy of the * volume table, and 'ubi_resize_volume()' will propogate this change * to the flash. */ ubi->vtbl[vol_id].flags &= ~UBI_VTBL_AUTORESIZE_FLG; if (ubi->avail_pebs == 0) { struct ubi_vtbl_record vtbl_rec; /* * No avalilable PEBs to re-size the volume, clear the flag on * flash and exit. */ memcpy(&vtbl_rec, &ubi->vtbl[vol_id], sizeof(struct ubi_vtbl_record)); err = ubi_change_vtbl_record(ubi, vol_id, &vtbl_rec); if (err) ubi_err("cannot clean auto-resize flag for volume %d", vol_id); } else { desc.vol = vol; err = ubi_resize_volume(&desc, old_reserved_pebs + ubi->avail_pebs); if (err) ubi_err("cannot auto-resize volume %d", vol_id); } if (err) return err; ubi_msg("volume %d (\"%s\") re-sized from %d to %d LEBs", vol_id, vol->name, old_reserved_pebs, vol->reserved_pebs); return 0; } /** * ubi_attach_mtd_dev - attach an MTD device. * @mtd_dev: MTD device description object Loading Loading @@ -702,6 +748,12 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, int vid_hdr_offset) ubi->mtd = mtd; ubi->ubi_num = ubi_num; ubi->vid_hdr_offset = vid_hdr_offset; ubi->autoresize_vol_id = -1; mutex_init(&ubi->buf_mutex); mutex_init(&ubi->ckvol_mutex); mutex_init(&ubi->volumes_mutex); spin_lock_init(&ubi->volumes_lock); dbg_msg("attaching mtd%d to ubi%d: VID header offset %d", mtd->index, ubi_num, vid_hdr_offset); Loading @@ -710,8 +762,6 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, int vid_hdr_offset) if (err) goto out_free; mutex_init(&ubi->buf_mutex); mutex_init(&ubi->ckvol_mutex); ubi->peb_buf1 = vmalloc(ubi->peb_size); if (!ubi->peb_buf1) goto out_free; Loading @@ -733,6 +783,12 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, int vid_hdr_offset) goto out_free; } if (ubi->autoresize_vol_id != -1) { err = autoresize(ubi, ubi->autoresize_vol_id); if (err) goto out_detach; } err = uif_init(ubi); if (err) goto out_detach; Loading Loading @@ -857,20 +913,6 @@ int ubi_detach_mtd_dev(int ubi_num, int anyway) return 0; } /** * ltree_entry_ctor - lock tree entries slab cache constructor. * @obj: the lock-tree entry to construct * @cache: the lock tree entry slab cache * @flags: constructor flags */ static void ltree_entry_ctor(struct kmem_cache *cache, void *obj) { struct ubi_ltree_entry *le = obj; le->users = 0; init_rwsem(&le->mutex); } /** * find_mtd_device - open an MTD device by its name or number. * @mtd_dev: name or number of the device Loading Loading @@ -933,17 +975,11 @@ static int __init ubi_init(void) goto out_version; } ubi_ltree_slab = kmem_cache_create("ubi_ltree_slab", sizeof(struct ubi_ltree_entry), 0, 0, <ree_entry_ctor); if (!ubi_ltree_slab) goto out_dev_unreg; ubi_wl_entry_slab = kmem_cache_create("ubi_wl_entry_slab", sizeof(struct ubi_wl_entry), 0, 0, NULL); if (!ubi_wl_entry_slab) goto out_ltree; goto out_dev_unreg; /* Attach MTD devices */ for (i = 0; i < mtd_devs; i++) { Loading Loading @@ -980,8 +1016,6 @@ out_detach: mutex_unlock(&ubi_devices_mutex); } kmem_cache_destroy(ubi_wl_entry_slab); out_ltree: kmem_cache_destroy(ubi_ltree_slab); out_dev_unreg: misc_deregister(&ubi_ctrl_cdev); out_version: Loading @@ -1005,7 +1039,6 @@ static void __exit ubi_exit(void) mutex_unlock(&ubi_devices_mutex); } kmem_cache_destroy(ubi_wl_entry_slab); kmem_cache_destroy(ubi_ltree_slab); misc_deregister(&ubi_ctrl_cdev); class_remove_file(ubi_class, &ubi_version); class_destroy(ubi_class); Loading Loading @@ -1066,7 +1099,7 @@ static int __init ubi_mtd_param_parse(const char *val, struct kernel_param *kp) struct mtd_dev_param *p; char buf[MTD_PARAM_LEN_MAX]; char *pbuf = &buf[0]; char *tokens[3] = {NULL, NULL, NULL}; char *tokens[2] = {NULL, NULL}; if (!val) return -EINVAL; Loading Loading @@ -1096,7 +1129,7 @@ static int __init ubi_mtd_param_parse(const char *val, struct kernel_param *kp) if (buf[len - 1] == '\n') buf[len - 1] = '\0'; for (i = 0; i < 3; i++) for (i = 0; i < 2; i++) tokens[i] = strsep(&pbuf, ","); if (pbuf) { Loading
drivers/mtd/ubi/cdev.c +64 −18 Original line number Diff line number Diff line Loading @@ -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); Loading Loading @@ -184,13 +191,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"); Loading @@ -204,7 +211,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; Loading Loading @@ -274,7 +281,7 @@ static ssize_t vol_cdev_direct_write(struct file *file, const char __user *buf, 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; Loading Loading @@ -351,23 +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->vol_id, 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; if (vol->changing_leb) { revoke_exclusive(desc, UBI_READWRITE); return count; } err = ubi_check_volume(ubi, vol->vol_id); if (err < 0) return err; Loading @@ -382,7 +398,6 @@ static ssize_t vol_cdev_write(struct file *file, const char __user *buf, revoke_exclusive(desc, UBI_READWRITE); } *offp += count; return count; } Loading Loading @@ -427,11 +442,46 @@ 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; } /* 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; } file->f_pos = 0; /* 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; } Loading @@ -447,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; } Loading @@ -457,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) Loading
drivers/mtd/ubi/eba.c +19 −21 Original line number Diff line number Diff line Loading @@ -78,7 +78,7 @@ static unsigned long long next_sqnum(struct ubi_device *ubi) */ static int ubi_get_compat(const struct ubi_device *ubi, int vol_id) { if (vol_id == UBI_LAYOUT_VOL_ID) if (vol_id == UBI_LAYOUT_VOLUME_ID) return UBI_LAYOUT_VOLUME_COMPAT; return 0; } Loading Loading @@ -137,10 +137,12 @@ static struct ubi_ltree_entry *ltree_add_entry(struct ubi_device *ubi, { struct ubi_ltree_entry *le, *le1, *le_free; le = kmem_cache_alloc(ubi_ltree_slab, GFP_NOFS); le = kmalloc(sizeof(struct ubi_ltree_entry), GFP_NOFS); if (!le) return ERR_PTR(-ENOMEM); le->users = 0; init_rwsem(&le->mutex); le->vol_id = vol_id; le->lnum = lnum; Loading Loading @@ -188,7 +190,7 @@ static struct ubi_ltree_entry *ltree_add_entry(struct ubi_device *ubi, spin_unlock(&ubi->ltree_lock); if (le_free) kmem_cache_free(ubi_ltree_slab, le_free); kfree(le_free); return le; } Loading Loading @@ -236,7 +238,7 @@ static void leb_read_unlock(struct ubi_device *ubi, int vol_id, int lnum) up_read(&le->mutex); if (free) kmem_cache_free(ubi_ltree_slab, le); kfree(le); } /** Loading Loading @@ -292,7 +294,7 @@ static int leb_write_trylock(struct ubi_device *ubi, int vol_id, int lnum) free = 0; spin_unlock(&ubi->ltree_lock); if (free) kmem_cache_free(ubi_ltree_slab, le); kfree(le); return 1; } Loading Loading @@ -321,7 +323,7 @@ static void leb_write_unlock(struct ubi_device *ubi, int vol_id, int lnum) up_write(&le->mutex); if (free) kmem_cache_free(ubi_ltree_slab, le); kfree(le); } /** Loading @@ -339,9 +341,6 @@ int ubi_eba_unmap_leb(struct ubi_device *ubi, struct ubi_volume *vol, { int err, pnum, vol_id = vol->vol_id; ubi_assert(ubi->ref_count > 0); ubi_assert(vol->ref_count > 0); if (ubi->ro_mode) return -EROFS; Loading Loading @@ -390,9 +389,6 @@ int ubi_eba_read_leb(struct ubi_device *ubi, struct ubi_volume *vol, int lnum, struct ubi_vid_hdr *vid_hdr; uint32_t uninitialized_var(crc); ubi_assert(ubi->ref_count > 0); ubi_assert(vol->ref_count > 0); err = leb_read_lock(ubi, vol_id, lnum); if (err) return err; Loading Loading @@ -616,9 +612,6 @@ int ubi_eba_write_leb(struct ubi_device *ubi, struct ubi_volume *vol, int lnum, int err, pnum, tries = 0, vol_id = vol->vol_id; struct ubi_vid_hdr *vid_hdr; ubi_assert(ubi->ref_count > 0); ubi_assert(vol->ref_count > 0); if (ubi->ro_mode) return -EROFS; Loading Loading @@ -752,9 +745,6 @@ int ubi_eba_write_leb_st(struct ubi_device *ubi, struct ubi_volume *vol, struct ubi_vid_hdr *vid_hdr; uint32_t crc; ubi_assert(ubi->ref_count > 0); ubi_assert(vol->ref_count > 0); if (ubi->ro_mode) return -EROFS; Loading Loading @@ -869,12 +859,20 @@ int ubi_eba_atomic_leb_change(struct ubi_device *ubi, struct ubi_volume *vol, struct ubi_vid_hdr *vid_hdr; uint32_t crc; ubi_assert(ubi->ref_count > 0); ubi_assert(vol->ref_count > 0); if (ubi->ro_mode) return -EROFS; if (len == 0) { /* * Special case when data length is zero. In this case the LEB * has to be unmapped and mapped somewhere else. */ err = ubi_eba_unmap_leb(ubi, vol, lnum); if (err) return err; return ubi_eba_write_leb(ubi, vol, lnum, NULL, 0, 0, dtype); } vid_hdr = ubi_zalloc_vid_hdr(ubi, GFP_NOFS); if (!vid_hdr) return -ENOMEM; Loading
drivers/mtd/ubi/kapi.c +4 −6 Original line number Diff line number Diff line Loading @@ -480,9 +480,9 @@ int ubi_leb_erase(struct ubi_volume_desc *desc, int lnum) { struct ubi_volume *vol = desc->vol; struct ubi_device *ubi = vol->ubi; int err, vol_id = vol->vol_id; int err; dbg_msg("erase LEB %d:%d", vol_id, lnum); dbg_msg("erase LEB %d:%d", vol->vol_id, lnum); if (desc->mode == UBI_READONLY || vol->vol_type == UBI_STATIC_VOLUME) return -EROFS; Loading Loading @@ -541,9 +541,8 @@ int ubi_leb_unmap(struct ubi_volume_desc *desc, int lnum) { 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); dbg_msg("unmap LEB %d:%d", vol->vol_id, lnum); if (desc->mode == UBI_READONLY || vol->vol_type == UBI_STATIC_VOLUME) return -EROFS; Loading Loading @@ -579,9 +578,8 @@ 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); dbg_msg("unmap LEB %d:%d", vol->vol_id, lnum); if (desc->mode == UBI_READONLY || vol->vol_type == UBI_STATIC_VOLUME) return -EROFS; Loading
drivers/mtd/ubi/scan.c +7 −3 Original line number Diff line number Diff line Loading @@ -286,9 +286,14 @@ static int compare_lebs(struct ubi_device *ubi, const struct ubi_scan_leb *seb, * FIXME: but this is anyway obsolete and will be removed at * some point. */ dbg_bld("using old crappy leb_ver stuff"); if (v1 == v2) { ubi_err("PEB %d and PEB %d have the same version %lld", seb->pnum, pnum, v1); return -EINVAL; } abs = v1 - v2; if (abs < 0) abs = -abs; Loading Loading @@ -390,7 +395,6 @@ out_free_buf: vfree(buf); out_free_vidh: ubi_free_vid_hdr(ubi, vh); ubi_assert(err < 0); return err; } Loading Loading @@ -854,7 +858,7 @@ static int process_eb(struct ubi_device *ubi, struct ubi_scan_info *si, int pnum } vol_id = be32_to_cpu(vidh->vol_id); if (vol_id > UBI_MAX_VOLUMES && vol_id != UBI_LAYOUT_VOL_ID) { if (vol_id > UBI_MAX_VOLUMES && vol_id != UBI_LAYOUT_VOLUME_ID) { int lnum = be32_to_cpu(vidh->lnum); /* Unsupported internal volume */ Loading