brintos

brintos / linux-shallow public Read only

0
0
Text · 22.6 KiB · 5a3558b Raw
847 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 * Copyright (c) International Business Machines Corp., 20064 *5 * Author: Artem Bityutskiy (Битюцкий Артём)6 */7 8/*9 * This file contains implementation of volume creation, deletion, updating and10 * resizing.11 */12 13#include <linux/err.h>14#include <linux/math64.h>15#include <linux/slab.h>16#include <linux/export.h>17#include "ubi.h"18 19static int self_check_volumes(struct ubi_device *ubi);20 21static ssize_t vol_attribute_show(struct device *dev,22				  struct device_attribute *attr, char *buf);23 24/* Device attributes corresponding to files in '/<sysfs>/class/ubi/ubiX_Y' */25static struct device_attribute attr_vol_reserved_ebs =26	__ATTR(reserved_ebs, S_IRUGO, vol_attribute_show, NULL);27static struct device_attribute attr_vol_type =28	__ATTR(type, S_IRUGO, vol_attribute_show, NULL);29static struct device_attribute attr_vol_name =30	__ATTR(name, S_IRUGO, vol_attribute_show, NULL);31static struct device_attribute attr_vol_corrupted =32	__ATTR(corrupted, S_IRUGO, vol_attribute_show, NULL);33static struct device_attribute attr_vol_alignment =34	__ATTR(alignment, S_IRUGO, vol_attribute_show, NULL);35static struct device_attribute attr_vol_usable_eb_size =36	__ATTR(usable_eb_size, S_IRUGO, vol_attribute_show, NULL);37static struct device_attribute attr_vol_data_bytes =38	__ATTR(data_bytes, S_IRUGO, vol_attribute_show, NULL);39static struct device_attribute attr_vol_upd_marker =40	__ATTR(upd_marker, S_IRUGO, vol_attribute_show, NULL);41 42/*43 * "Show" method for files in '/<sysfs>/class/ubi/ubiX_Y/'.44 *45 * Consider a situation:46 * A. process 1 opens a sysfs file related to volume Y, say47 *    /<sysfs>/class/ubi/ubiX_Y/reserved_ebs;48 * B. process 2 removes volume Y;49 * C. process 1 starts reading the /<sysfs>/class/ubi/ubiX_Y/reserved_ebs file;50 *51 * In this situation, this function will return %-ENODEV because it will find52 * out that the volume was removed from the @ubi->volumes array.53 */54static ssize_t vol_attribute_show(struct device *dev,55				  struct device_attribute *attr, char *buf)56{57	int ret;58	struct ubi_volume *vol = container_of(dev, struct ubi_volume, dev);59	struct ubi_device *ubi = vol->ubi;60 61	spin_lock(&ubi->volumes_lock);62	if (!ubi->volumes[vol->vol_id] || ubi->volumes[vol->vol_id]->is_dead) {63		spin_unlock(&ubi->volumes_lock);64		return -ENODEV;65	}66	/* Take a reference to prevent volume removal */67	vol->ref_count += 1;68	spin_unlock(&ubi->volumes_lock);69 70	if (attr == &attr_vol_reserved_ebs)71		ret = sprintf(buf, "%d\n", vol->reserved_pebs);72	else if (attr == &attr_vol_type) {73		const char *tp;74 75		if (vol->vol_type == UBI_DYNAMIC_VOLUME)76			tp = "dynamic";77		else78			tp = "static";79		ret = sprintf(buf, "%s\n", tp);80	} else if (attr == &attr_vol_name)81		ret = sprintf(buf, "%s\n", vol->name);82	else if (attr == &attr_vol_corrupted)83		ret = sprintf(buf, "%d\n", vol->corrupted);84	else if (attr == &attr_vol_alignment)85		ret = sprintf(buf, "%d\n", vol->alignment);86	else if (attr == &attr_vol_usable_eb_size)87		ret = sprintf(buf, "%d\n", vol->usable_leb_size);88	else if (attr == &attr_vol_data_bytes)89		ret = sprintf(buf, "%lld\n", vol->used_bytes);90	else if (attr == &attr_vol_upd_marker)91		ret = sprintf(buf, "%d\n", vol->upd_marker);92	else93		/* This must be a bug */94		ret = -EINVAL;95 96	/* We've done the operation, drop volume and UBI device references */97	spin_lock(&ubi->volumes_lock);98	vol->ref_count -= 1;99	ubi_assert(vol->ref_count >= 0);100	spin_unlock(&ubi->volumes_lock);101	return ret;102}103 104static struct attribute *volume_dev_attrs[] = {105	&attr_vol_reserved_ebs.attr,106	&attr_vol_type.attr,107	&attr_vol_name.attr,108	&attr_vol_corrupted.attr,109	&attr_vol_alignment.attr,110	&attr_vol_usable_eb_size.attr,111	&attr_vol_data_bytes.attr,112	&attr_vol_upd_marker.attr,113	NULL114};115ATTRIBUTE_GROUPS(volume_dev);116 117/* Release method for volume devices */118static void vol_release(struct device *dev)119{120	struct ubi_volume *vol = container_of(dev, struct ubi_volume, dev);121 122	ubi_eba_replace_table(vol, NULL);123	ubi_fastmap_destroy_checkmap(vol);124	kfree(vol);125}126 127static struct fwnode_handle *find_volume_fwnode(struct ubi_volume *vol)128{129	struct fwnode_handle *fw_vols, *fw_vol;130	const char *volname;131	u32 volid;132 133	fw_vols = device_get_named_child_node(vol->dev.parent->parent, "volumes");134	if (!fw_vols)135		return NULL;136 137	fwnode_for_each_child_node(fw_vols, fw_vol) {138		if (!fwnode_property_read_string(fw_vol, "volname", &volname) &&139		    strncmp(volname, vol->name, vol->name_len))140			continue;141 142		if (!fwnode_property_read_u32(fw_vol, "volid", &volid) &&143		    vol->vol_id != volid)144			continue;145 146		return fw_vol;147	}148 149	return NULL;150}151 152/**153 * ubi_create_volume - create volume.154 * @ubi: UBI device description object155 * @req: volume creation request156 *157 * This function creates volume described by @req. If @req->vol_id id158 * %UBI_VOL_NUM_AUTO, this function automatically assign ID to the new volume159 * and saves it in @req->vol_id. Returns zero in case of success and a negative160 * error code in case of failure. Note, the caller has to have the161 * @ubi->device_mutex locked.162 */163int ubi_create_volume(struct ubi_device *ubi, struct ubi_mkvol_req *req)164{165	int i, err, vol_id = req->vol_id;166	struct ubi_volume *vol;167	struct ubi_vtbl_record vtbl_rec;168	struct ubi_eba_table *eba_tbl = NULL;169 170	if (ubi->ro_mode)171		return -EROFS;172 173	vol = kzalloc(sizeof(struct ubi_volume), GFP_KERNEL);174	if (!vol)175		return -ENOMEM;176 177	device_initialize(&vol->dev);178	vol->dev.release = vol_release;179	vol->dev.parent = &ubi->dev;180	vol->dev.class = &ubi_class;181	vol->dev.groups = volume_dev_groups;182 183	if (req->flags & UBI_VOL_SKIP_CRC_CHECK_FLG)184		vol->skip_check = 1;185 186	spin_lock(&ubi->volumes_lock);187	if (vol_id == UBI_VOL_NUM_AUTO) {188		/* Find unused volume ID */189		dbg_gen("search for vacant volume ID");190		for (i = 0; i < ubi->vtbl_slots; i++)191			if (!ubi->volumes[i]) {192				vol_id = i;193				break;194			}195 196		if (vol_id == UBI_VOL_NUM_AUTO) {197			ubi_err(ubi, "out of volume IDs");198			err = -ENFILE;199			goto out_unlock;200		}201		req->vol_id = vol_id;202	}203 204	dbg_gen("create device %d, volume %d, %llu bytes, type %d, name %s",205		ubi->ubi_num, vol_id, (unsigned long long)req->bytes,206		(int)req->vol_type, req->name);207 208	/* Ensure that this volume does not exist */209	err = -EEXIST;210	if (ubi->volumes[vol_id]) {211		ubi_err(ubi, "volume %d already exists", vol_id);212		goto out_unlock;213	}214 215	/* Ensure that the name is unique */216	for (i = 0; i < ubi->vtbl_slots; i++)217		if (ubi->volumes[i] && !ubi->volumes[i]->is_dead &&218		    ubi->volumes[i]->name_len == req->name_len &&219		    !strcmp(ubi->volumes[i]->name, req->name)) {220			ubi_err(ubi, "volume \"%s\" exists (ID %d)",221				req->name, i);222			goto out_unlock;223		}224 225	/* Calculate how many eraseblocks are requested */226	vol->usable_leb_size = ubi->leb_size - ubi->leb_size % req->alignment;227	vol->reserved_pebs = div_u64(req->bytes + vol->usable_leb_size - 1,228				     vol->usable_leb_size);229 230	/* Reserve physical eraseblocks */231	if (vol->reserved_pebs > ubi->avail_pebs) {232		ubi_err(ubi, "not enough PEBs, only %d available",233			ubi->avail_pebs);234		if (ubi->corr_peb_count)235			ubi_err(ubi, "%d PEBs are corrupted and not used",236				ubi->corr_peb_count);237		err = -ENOSPC;238		goto out_unlock;239	}240	ubi->avail_pebs -= vol->reserved_pebs;241	ubi->rsvd_pebs += vol->reserved_pebs;242	spin_unlock(&ubi->volumes_lock);243 244	vol->vol_id    = vol_id;245	vol->alignment = req->alignment;246	vol->data_pad  = ubi->leb_size % vol->alignment;247	vol->vol_type  = req->vol_type;248	vol->name_len  = req->name_len;249	memcpy(vol->name, req->name, vol->name_len);250	vol->ubi = ubi;251	device_set_node(&vol->dev, find_volume_fwnode(vol));252 253	/*254	 * Finish all pending erases because there may be some LEBs belonging255	 * to the same volume ID.256	 */257	err = ubi_wl_flush(ubi, vol_id, UBI_ALL);258	if (err)259		goto out_acc;260 261	eba_tbl = ubi_eba_create_table(vol, vol->reserved_pebs);262	if (IS_ERR(eba_tbl)) {263		err = PTR_ERR(eba_tbl);264		goto out_acc;265	}266 267	ubi_eba_replace_table(vol, eba_tbl);268 269	if (vol->vol_type == UBI_DYNAMIC_VOLUME) {270		vol->used_ebs = vol->reserved_pebs;271		vol->last_eb_bytes = vol->usable_leb_size;272		vol->used_bytes =273			(long long)vol->used_ebs * vol->usable_leb_size;274	} else {275		vol->used_ebs = div_u64_rem(vol->used_bytes,276					    vol->usable_leb_size,277					    &vol->last_eb_bytes);278		if (vol->last_eb_bytes != 0)279			vol->used_ebs += 1;280		else281			vol->last_eb_bytes = vol->usable_leb_size;282	}283 284	/* Make volume "available" before it becomes accessible via sysfs */285	spin_lock(&ubi->volumes_lock);286	ubi->volumes[vol_id] = vol;287	ubi->vol_count += 1;288	spin_unlock(&ubi->volumes_lock);289 290	/* Register character device for the volume */291	cdev_init(&vol->cdev, &ubi_vol_cdev_operations);292	vol->cdev.owner = THIS_MODULE;293 294	vol->dev.devt = MKDEV(MAJOR(ubi->cdev.dev), vol_id + 1);295	dev_set_name(&vol->dev, "%s_%d", ubi->ubi_name, vol->vol_id);296	err = cdev_device_add(&vol->cdev, &vol->dev);297	if (err) {298		ubi_err(ubi, "cannot add device");299		goto out_mapping;300	}301 302	/* Fill volume table record */303	memset(&vtbl_rec, 0, sizeof(struct ubi_vtbl_record));304	vtbl_rec.reserved_pebs = cpu_to_be32(vol->reserved_pebs);305	vtbl_rec.alignment     = cpu_to_be32(vol->alignment);306	vtbl_rec.data_pad      = cpu_to_be32(vol->data_pad);307	vtbl_rec.name_len      = cpu_to_be16(vol->name_len);308	if (vol->vol_type == UBI_DYNAMIC_VOLUME)309		vtbl_rec.vol_type = UBI_VID_DYNAMIC;310	else311		vtbl_rec.vol_type = UBI_VID_STATIC;312 313	if (vol->skip_check)314		vtbl_rec.flags |= UBI_VTBL_SKIP_CRC_CHECK_FLG;315 316	memcpy(vtbl_rec.name, vol->name, vol->name_len);317 318	err = ubi_change_vtbl_record(ubi, vol_id, &vtbl_rec);319	if (err)320		goto out_sysfs;321 322	ubi_volume_notify(ubi, vol, UBI_VOLUME_ADDED);323	self_check_volumes(ubi);324	return err;325 326out_sysfs:327	/*328	 * We have registered our device, we should not free the volume329	 * description object in this function in case of an error - it is330	 * freed by the release function.331	 */332	cdev_device_del(&vol->cdev, &vol->dev);333out_mapping:334	spin_lock(&ubi->volumes_lock);335	ubi->volumes[vol_id] = NULL;336	ubi->vol_count -= 1;337	spin_unlock(&ubi->volumes_lock);338out_acc:339	spin_lock(&ubi->volumes_lock);340	ubi->rsvd_pebs -= vol->reserved_pebs;341	ubi->avail_pebs += vol->reserved_pebs;342out_unlock:343	spin_unlock(&ubi->volumes_lock);344	put_device(&vol->dev);345	ubi_err(ubi, "cannot create volume %d, error %d", vol_id, err);346	return err;347}348 349/**350 * ubi_remove_volume - remove volume.351 * @desc: volume descriptor352 * @no_vtbl: do not change volume table if not zero353 *354 * This function removes volume described by @desc. The volume has to be opened355 * in "exclusive" mode. Returns zero in case of success and a negative error356 * code in case of failure. The caller has to have the @ubi->device_mutex357 * locked.358 */359int ubi_remove_volume(struct ubi_volume_desc *desc, int no_vtbl)360{361	struct ubi_volume *vol = desc->vol;362	struct ubi_device *ubi = vol->ubi;363	int i, err, vol_id = vol->vol_id, reserved_pebs = vol->reserved_pebs;364 365	dbg_gen("remove device %d, volume %d", ubi->ubi_num, vol_id);366	ubi_assert(desc->mode == UBI_EXCLUSIVE);367	ubi_assert(vol == ubi->volumes[vol_id]);368 369	if (ubi->ro_mode)370		return -EROFS;371 372	spin_lock(&ubi->volumes_lock);373	if (vol->ref_count > 1) {374		/*375		 * The volume is busy, probably someone is reading one of its376		 * sysfs files.377		 */378		err = -EBUSY;379		goto out_unlock;380	}381 382	/*383	 * Mark volume as dead at this point to prevent that anyone384	 * can take a reference to the volume from now on.385	 * This is necessary as we have to release the spinlock before386	 * calling ubi_volume_notify.387	 */388	vol->is_dead = true;389	spin_unlock(&ubi->volumes_lock);390 391	ubi_volume_notify(ubi, vol, UBI_VOLUME_SHUTDOWN);392 393	spin_lock(&ubi->volumes_lock);394	ubi->volumes[vol_id] = NULL;395	spin_unlock(&ubi->volumes_lock);396 397	if (!no_vtbl) {398		err = ubi_change_vtbl_record(ubi, vol_id, NULL);399		if (err)400			goto out_err;401	}402 403	for (i = 0; i < vol->reserved_pebs; i++) {404		err = ubi_eba_unmap_leb(ubi, vol, i);405		if (err)406			goto out_err;407	}408 409	cdev_device_del(&vol->cdev, &vol->dev);410	put_device(&vol->dev);411 412	spin_lock(&ubi->volumes_lock);413	ubi->rsvd_pebs -= reserved_pebs;414	ubi->avail_pebs += reserved_pebs;415	ubi_update_reserved(ubi);416	ubi->vol_count -= 1;417	spin_unlock(&ubi->volumes_lock);418 419	ubi_volume_notify(ubi, vol, UBI_VOLUME_REMOVED);420	if (!no_vtbl)421		self_check_volumes(ubi);422 423	return 0;424 425out_err:426	ubi_err(ubi, "cannot remove volume %d, error %d", vol_id, err);427	spin_lock(&ubi->volumes_lock);428	ubi->volumes[vol_id] = vol;429out_unlock:430	spin_unlock(&ubi->volumes_lock);431	return err;432}433 434/**435 * ubi_resize_volume - re-size volume.436 * @desc: volume descriptor437 * @reserved_pebs: new size in physical eraseblocks438 *439 * This function re-sizes the volume and returns zero in case of success, and a440 * negative error code in case of failure. The caller has to have the441 * @ubi->device_mutex locked.442 */443int ubi_resize_volume(struct ubi_volume_desc *desc, int reserved_pebs)444{445	int i, err, pebs;446	struct ubi_volume *vol = desc->vol;447	struct ubi_device *ubi = vol->ubi;448	struct ubi_vtbl_record vtbl_rec;449	struct ubi_eba_table *new_eba_tbl = NULL;450	struct ubi_eba_table *old_eba_tbl = NULL;451	int vol_id = vol->vol_id;452 453	if (ubi->ro_mode)454		return -EROFS;455 456	dbg_gen("re-size device %d, volume %d to from %d to %d PEBs",457		ubi->ubi_num, vol_id, vol->reserved_pebs, reserved_pebs);458 459	if (vol->vol_type == UBI_STATIC_VOLUME &&460	    reserved_pebs < vol->used_ebs) {461		ubi_err(ubi, "too small size %d, %d LEBs contain data",462			reserved_pebs, vol->used_ebs);463		return -EINVAL;464	}465 466	/* If the size is the same, we have nothing to do */467	if (reserved_pebs == vol->reserved_pebs)468		return 0;469 470	new_eba_tbl = ubi_eba_create_table(vol, reserved_pebs);471	if (IS_ERR(new_eba_tbl))472		return PTR_ERR(new_eba_tbl);473 474	spin_lock(&ubi->volumes_lock);475	if (vol->ref_count > 1) {476		spin_unlock(&ubi->volumes_lock);477		err = -EBUSY;478		goto out_free;479	}480	spin_unlock(&ubi->volumes_lock);481 482	/* Reserve physical eraseblocks */483	pebs = reserved_pebs - vol->reserved_pebs;484	if (pebs > 0) {485		spin_lock(&ubi->volumes_lock);486		if (pebs > ubi->avail_pebs) {487			ubi_err(ubi, "not enough PEBs: requested %d, available %d",488				pebs, ubi->avail_pebs);489			if (ubi->corr_peb_count)490				ubi_err(ubi, "%d PEBs are corrupted and not used",491					ubi->corr_peb_count);492			spin_unlock(&ubi->volumes_lock);493			err = -ENOSPC;494			goto out_free;495		}496 497		ubi->avail_pebs -= pebs;498		ubi->rsvd_pebs += pebs;499		ubi_eba_copy_table(vol, new_eba_tbl, vol->reserved_pebs);500		old_eba_tbl = vol->eba_tbl;501		vol->eba_tbl = new_eba_tbl;502		vol->reserved_pebs = reserved_pebs;503		spin_unlock(&ubi->volumes_lock);504	}505 506	if (pebs < 0) {507		for (i = 0; i < -pebs; i++) {508			err = ubi_eba_unmap_leb(ubi, vol, reserved_pebs + i);509			if (err)510				goto out_free;511		}512		spin_lock(&ubi->volumes_lock);513		ubi->rsvd_pebs += pebs;514		ubi->avail_pebs -= pebs;515		ubi_update_reserved(ubi);516		ubi_eba_copy_table(vol, new_eba_tbl, reserved_pebs);517		old_eba_tbl = vol->eba_tbl;518		vol->eba_tbl = new_eba_tbl;519		vol->reserved_pebs = reserved_pebs;520		spin_unlock(&ubi->volumes_lock);521	}522 523	/*524	 * When we shrink a volume we have to flush all pending (erase) work.525	 * Otherwise it can happen that upon next attach UBI finds a LEB with526	 * lnum > highest_lnum and refuses to attach.527	 */528	if (pebs < 0) {529		err = ubi_wl_flush(ubi, vol_id, UBI_ALL);530		if (err)531			goto out_acc;532	}533 534	/* Change volume table record */535	vtbl_rec = ubi->vtbl[vol_id];536	vtbl_rec.reserved_pebs = cpu_to_be32(reserved_pebs);537	err = ubi_change_vtbl_record(ubi, vol_id, &vtbl_rec);538	if (err)539		goto out_acc;540 541	if (vol->vol_type == UBI_DYNAMIC_VOLUME) {542		vol->used_ebs = reserved_pebs;543		vol->last_eb_bytes = vol->usable_leb_size;544		vol->used_bytes =545			(long long)vol->used_ebs * vol->usable_leb_size;546	}547 548	/* destroy old table */549	ubi_eba_destroy_table(old_eba_tbl);550	ubi_volume_notify(ubi, vol, UBI_VOLUME_RESIZED);551	self_check_volumes(ubi);552	return err;553 554out_acc:555	spin_lock(&ubi->volumes_lock);556	vol->reserved_pebs = reserved_pebs - pebs;557	ubi->rsvd_pebs -= pebs;558	ubi->avail_pebs += pebs;559	if (pebs > 0)560		ubi_eba_copy_table(vol, old_eba_tbl, vol->reserved_pebs);561	else562		ubi_eba_copy_table(vol, old_eba_tbl, reserved_pebs);563	vol->eba_tbl = old_eba_tbl;564	spin_unlock(&ubi->volumes_lock);565out_free:566	ubi_eba_destroy_table(new_eba_tbl);567	return err;568}569 570/**571 * ubi_rename_volumes - re-name UBI volumes.572 * @ubi: UBI device description object573 * @rename_list: list of &struct ubi_rename_entry objects574 *575 * This function re-names or removes volumes specified in the re-name list.576 * Returns zero in case of success and a negative error code in case of577 * failure.578 */579int ubi_rename_volumes(struct ubi_device *ubi, struct list_head *rename_list)580{581	int err;582	struct ubi_rename_entry *re;583 584	err = ubi_vtbl_rename_volumes(ubi, rename_list);585	if (err)586		return err;587 588	list_for_each_entry(re, rename_list, list) {589		if (re->remove) {590			err = ubi_remove_volume(re->desc, 1);591			if (err)592				break;593		} else {594			struct ubi_volume *vol = re->desc->vol;595 596			spin_lock(&ubi->volumes_lock);597			vol->name_len = re->new_name_len;598			memcpy(vol->name, re->new_name, re->new_name_len + 1);599			spin_unlock(&ubi->volumes_lock);600			ubi_volume_notify(ubi, vol, UBI_VOLUME_RENAMED);601		}602	}603 604	if (!err)605		self_check_volumes(ubi);606	return err;607}608 609/**610 * ubi_add_volume - add volume.611 * @ubi: UBI device description object612 * @vol: volume description object613 *614 * This function adds an existing volume and initializes all its data615 * structures. Returns zero in case of success and a negative error code in616 * case of failure.617 */618int ubi_add_volume(struct ubi_device *ubi, struct ubi_volume *vol)619{620	int err, vol_id = vol->vol_id;621	dev_t dev;622 623	dbg_gen("add volume %d", vol_id);624 625	/* Register character device for the volume */626	cdev_init(&vol->cdev, &ubi_vol_cdev_operations);627	vol->cdev.owner = THIS_MODULE;628	dev = MKDEV(MAJOR(ubi->cdev.dev), vol->vol_id + 1);629	err = cdev_add(&vol->cdev, dev, 1);630	if (err) {631		ubi_err(ubi, "cannot add character device for volume %d, error %d",632			vol_id, err);633		vol_release(&vol->dev);634		return err;635	}636 637	vol->dev.release = vol_release;638	vol->dev.parent = &ubi->dev;639	vol->dev.devt = dev;640	vol->dev.class = &ubi_class;641	vol->dev.groups = volume_dev_groups;642	dev_set_name(&vol->dev, "%s_%d", ubi->ubi_name, vol->vol_id);643	device_set_node(&vol->dev, find_volume_fwnode(vol));644	err = device_register(&vol->dev);645	if (err) {646		cdev_del(&vol->cdev);647		put_device(&vol->dev);648		return err;649	}650 651	self_check_volumes(ubi);652	return err;653}654 655/**656 * ubi_free_volume - free volume.657 * @ubi: UBI device description object658 * @vol: volume description object659 *660 * This function frees all resources for volume @vol but does not remove it.661 * Used only when the UBI device is detached.662 */663void ubi_free_volume(struct ubi_device *ubi, struct ubi_volume *vol)664{665	dbg_gen("free volume %d", vol->vol_id);666 667	ubi->volumes[vol->vol_id] = NULL;668	cdev_del(&vol->cdev);669	device_unregister(&vol->dev);670}671 672/**673 * self_check_volume - check volume information.674 * @ubi: UBI device description object675 * @vol_id: volume ID676 *677 * Returns zero if volume is all right and a negative error code if not.678 */679static int self_check_volume(struct ubi_device *ubi, int vol_id)680{681	int idx = vol_id2idx(ubi, vol_id);682	int reserved_pebs, alignment, data_pad, vol_type, name_len, upd_marker;683	const struct ubi_volume *vol;684	long long n;685	const char *name;686 687	spin_lock(&ubi->volumes_lock);688	reserved_pebs = be32_to_cpu(ubi->vtbl[vol_id].reserved_pebs);689	vol = ubi->volumes[idx];690 691	if (!vol) {692		if (reserved_pebs) {693			ubi_err(ubi, "no volume info, but volume exists");694			goto fail;695		}696		spin_unlock(&ubi->volumes_lock);697		return 0;698	}699 700	if (vol->reserved_pebs < 0 || vol->alignment < 0 || vol->data_pad < 0 ||701	    vol->name_len < 0) {702		ubi_err(ubi, "negative values");703		goto fail;704	}705	if (vol->alignment > ubi->leb_size || vol->alignment == 0) {706		ubi_err(ubi, "bad alignment");707		goto fail;708	}709 710	n = vol->alignment & (ubi->min_io_size - 1);711	if (vol->alignment != 1 && n) {712		ubi_err(ubi, "alignment is not multiple of min I/O unit");713		goto fail;714	}715 716	n = ubi->leb_size % vol->alignment;717	if (vol->data_pad != n) {718		ubi_err(ubi, "bad data_pad, has to be %lld", n);719		goto fail;720	}721 722	if (vol->vol_type != UBI_DYNAMIC_VOLUME &&723	    vol->vol_type != UBI_STATIC_VOLUME) {724		ubi_err(ubi, "bad vol_type");725		goto fail;726	}727 728	if (vol->upd_marker && vol->corrupted) {729		ubi_err(ubi, "update marker and corrupted simultaneously");730		goto fail;731	}732 733	if (vol->reserved_pebs > ubi->good_peb_count) {734		ubi_err(ubi, "too large reserved_pebs");735		goto fail;736	}737 738	n = ubi->leb_size - vol->data_pad;739	if (vol->usable_leb_size != ubi->leb_size - vol->data_pad) {740		ubi_err(ubi, "bad usable_leb_size, has to be %lld", n);741		goto fail;742	}743 744	if (vol->name_len > UBI_VOL_NAME_MAX) {745		ubi_err(ubi, "too long volume name, max is %d",746			UBI_VOL_NAME_MAX);747		goto fail;748	}749 750	n = strnlen(vol->name, vol->name_len + 1);751	if (n != vol->name_len) {752		ubi_err(ubi, "bad name_len %lld", n);753		goto fail;754	}755 756	n = (long long)vol->used_ebs * vol->usable_leb_size;757	if (vol->vol_type == UBI_DYNAMIC_VOLUME) {758		if (vol->corrupted) {759			ubi_err(ubi, "corrupted dynamic volume");760			goto fail;761		}762		if (vol->used_ebs != vol->reserved_pebs) {763			ubi_err(ubi, "bad used_ebs");764			goto fail;765		}766		if (vol->last_eb_bytes != vol->usable_leb_size) {767			ubi_err(ubi, "bad last_eb_bytes");768			goto fail;769		}770		if (vol->used_bytes != n) {771			ubi_err(ubi, "bad used_bytes");772			goto fail;773		}774 775		if (vol->skip_check) {776			ubi_err(ubi, "bad skip_check");777			goto fail;778		}779	} else {780		if (vol->used_ebs < 0 || vol->used_ebs > vol->reserved_pebs) {781			ubi_err(ubi, "bad used_ebs");782			goto fail;783		}784		if (vol->last_eb_bytes < 0 ||785		    vol->last_eb_bytes > vol->usable_leb_size) {786			ubi_err(ubi, "bad last_eb_bytes");787			goto fail;788		}789		if (vol->used_bytes < 0 || vol->used_bytes > n ||790		    vol->used_bytes < n - vol->usable_leb_size) {791			ubi_err(ubi, "bad used_bytes");792			goto fail;793		}794	}795 796	alignment  = be32_to_cpu(ubi->vtbl[vol_id].alignment);797	data_pad   = be32_to_cpu(ubi->vtbl[vol_id].data_pad);798	name_len   = be16_to_cpu(ubi->vtbl[vol_id].name_len);799	upd_marker = ubi->vtbl[vol_id].upd_marker;800	name       = &ubi->vtbl[vol_id].name[0];801	if (ubi->vtbl[vol_id].vol_type == UBI_VID_DYNAMIC)802		vol_type = UBI_DYNAMIC_VOLUME;803	else804		vol_type = UBI_STATIC_VOLUME;805 806	if (alignment != vol->alignment || data_pad != vol->data_pad ||807	    upd_marker != vol->upd_marker || vol_type != vol->vol_type ||808	    name_len != vol->name_len || strncmp(name, vol->name, name_len)) {809		ubi_err(ubi, "volume info is different");810		goto fail;811	}812 813	spin_unlock(&ubi->volumes_lock);814	return 0;815 816fail:817	ubi_err(ubi, "self-check failed for volume %d", vol_id);818	if (vol)819		ubi_dump_vol_info(vol);820	ubi_dump_vtbl_record(&ubi->vtbl[vol_id], vol_id);821	dump_stack();822	spin_unlock(&ubi->volumes_lock);823	return -EINVAL;824}825 826/**827 * self_check_volumes - check information about all volumes.828 * @ubi: UBI device description object829 *830 * Returns zero if volumes are all right and a negative error code if not.831 */832static int self_check_volumes(struct ubi_device *ubi)833{834	int i, err = 0;835 836	if (!ubi_dbg_chk_gen(ubi))837		return 0;838 839	for (i = 0; i < ubi->vtbl_slots; i++) {840		err = self_check_volume(ubi, i);841		if (err)842			break;843	}844 845	return err;846}847