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: (22 commits)
  UBI: always start the background thread
  UBI: fix gcc warning
  UBI: remove pre-sqnum images support
  UBI: fix kernel-doc errors and warnings
  UBI: fix checkpatch.pl errors and warnings
  UBI: bugfix - do not torture PEB needlessly
  UBI: rework scrubbing messages
  UBI: implement multiple volumes rename
  UBI: fix and re-work debugging stuff
  UBI: amend commentaries
  UBI: fix error message
  UBI: improve mkvol request validation
  UBI: add ubi_sync() interface
  UBI: fix 64-bit calculations
  UBI: fix LEB locking
  UBI: fix memory leak on error path
  UBI: do not forget to free internal volumes
  UBI: fix memory leak
  UBI: avoid unnecessary division operations
  UBI: fix buffer padding
  ...
  • Loading branch information
Linus Torvalds committed Jul 25, 2008
2 parents 93082f0 + d37e6bf commit 996abf0
Show file tree
Hide file tree
Showing 19 changed files with 1,008 additions and 616 deletions.
99 changes: 73 additions & 26 deletions drivers/mtd/ubi/build.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,14 +51,13 @@
* @name: MTD device name or number string
* @vid_hdr_offs: VID header offset
*/
struct mtd_dev_param
{
struct mtd_dev_param {
char name[MTD_PARAM_LEN_MAX];
int vid_hdr_offs;
};

/* Numbers of elements set in the @mtd_dev_param array */
static int mtd_devs = 0;
static int mtd_devs;

/* MTD devices specification parameters */
static struct mtd_dev_param mtd_dev_param[UBI_MAX_DEVICES];
Expand Down Expand Up @@ -160,8 +159,7 @@ void ubi_put_device(struct ubi_device *ubi)
}

/**
* ubi_get_by_major - get UBI device description object by character device
* major number.
* ubi_get_by_major - get UBI device by character device major number.
* @major: major number
*
* This function is similar to 'ubi_get_device()', but it searches the device
Expand Down Expand Up @@ -354,16 +352,35 @@ static void kill_volumes(struct ubi_device *ubi)
ubi_free_volume(ubi, ubi->volumes[i]);
}

/**
* free_user_volumes - free all user volumes.
* @ubi: UBI device description object
*
* Normally the volumes are freed at the release function of the volume device
* objects. However, on error paths the volumes have to be freed before the
* device objects have been initialized.
*/
static void free_user_volumes(struct ubi_device *ubi)
{
int i;

for (i = 0; i < ubi->vtbl_slots; i++)
if (ubi->volumes[i]) {
kfree(ubi->volumes[i]->eba_tbl);
kfree(ubi->volumes[i]);
}
}

/**
* uif_init - initialize user interfaces for an UBI device.
* @ubi: UBI device description object
*
* This function returns zero in case of success and a negative error code in
* case of failure.
* case of failure. Note, this function destroys all volumes if it failes.
*/
static int uif_init(struct ubi_device *ubi)
{
int i, err;
int i, err, do_free = 0;
dev_t dev;

sprintf(ubi->ubi_name, UBI_NAME_STR "%d", ubi->ubi_num);
Expand All @@ -384,7 +401,7 @@ static int uif_init(struct ubi_device *ubi)

ubi_assert(MINOR(dev) == 0);
cdev_init(&ubi->cdev, &ubi_cdev_operations);
dbg_msg("%s major is %u", ubi->ubi_name, MAJOR(dev));
dbg_gen("%s major is %u", ubi->ubi_name, MAJOR(dev));
ubi->cdev.owner = THIS_MODULE;

err = cdev_add(&ubi->cdev, dev, 1);
Expand All @@ -410,10 +427,13 @@ static int uif_init(struct ubi_device *ubi)

out_volumes:
kill_volumes(ubi);
do_free = 0;
out_sysfs:
ubi_sysfs_close(ubi);
cdev_del(&ubi->cdev);
out_unreg:
if (do_free)
free_user_volumes(ubi);
unregister_chrdev_region(ubi->cdev.dev, ubi->vtbl_slots + 1);
ubi_err("cannot initialize UBI %s, error %d", ubi->ubi_name, err);
return err;
Expand All @@ -422,6 +442,10 @@ static int uif_init(struct ubi_device *ubi)
/**
* uif_close - close user interfaces for an UBI device.
* @ubi: UBI device description object
*
* Note, since this function un-registers UBI volume device objects (@vol->dev),
* the memory allocated voe the volumes is freed as well (in the release
* function).
*/
static void uif_close(struct ubi_device *ubi)
{
Expand All @@ -431,6 +455,21 @@ static void uif_close(struct ubi_device *ubi)
unregister_chrdev_region(ubi->cdev.dev, ubi->vtbl_slots + 1);
}

/**
* free_internal_volumes - free internal volumes.
* @ubi: UBI device description object
*/
static void free_internal_volumes(struct ubi_device *ubi)
{
int i;

for (i = ubi->vtbl_slots;
i < ubi->vtbl_slots + UBI_INT_VOL_COUNT; i++) {
kfree(ubi->volumes[i]->eba_tbl);
kfree(ubi->volumes[i]);
}
}

/**
* attach_by_scanning - attach an MTD device using scanning method.
* @ubi: UBI device descriptor
Expand Down Expand Up @@ -475,14 +514,15 @@ static int attach_by_scanning(struct ubi_device *ubi)
out_wl:
ubi_wl_close(ubi);
out_vtbl:
free_internal_volumes(ubi);
vfree(ubi->vtbl);
out_si:
ubi_scan_destroy_si(si);
return err;
}

/**
* io_init - initialize I/O unit for a given UBI device.
* io_init - initialize I/O sub-system for a given UBI device.
* @ubi: UBI device description object
*
* If @ubi->vid_hdr_offset or @ubi->leb_start is zero, default offsets are
Expand Down Expand Up @@ -530,7 +570,11 @@ static int io_init(struct ubi_device *ubi)
ubi->min_io_size = ubi->mtd->writesize;
ubi->hdrs_min_io_size = ubi->mtd->writesize >> ubi->mtd->subpage_sft;

/* Make sure minimal I/O unit is power of 2 */
/*
* Make sure minimal I/O unit is power of 2. Note, there is no
* fundamental reason for this assumption. It is just an optimization
* which allows us to avoid costly division operations.
*/
if (!is_power_of_2(ubi->min_io_size)) {
ubi_err("min. I/O unit (%d) is not power of 2",
ubi->min_io_size);
Expand Down Expand Up @@ -581,7 +625,7 @@ static int io_init(struct ubi_device *ubi)
if (ubi->vid_hdr_offset < UBI_EC_HDR_SIZE ||
ubi->leb_start < ubi->vid_hdr_offset + UBI_VID_HDR_SIZE ||
ubi->leb_start > ubi->peb_size - UBI_VID_HDR_SIZE ||
ubi->leb_start % ubi->min_io_size) {
ubi->leb_start & (ubi->min_io_size - 1)) {
ubi_err("bad VID header (%d) or data offsets (%d)",
ubi->vid_hdr_offset, ubi->leb_start);
return -EINVAL;
Expand Down Expand Up @@ -646,7 +690,7 @@ static int autoresize(struct ubi_device *ubi, int vol_id)

/*
* Clear the auto-resize flag in the volume in-memory copy of the
* volume table, and 'ubi_resize_volume()' will propogate this change
* volume table, and 'ubi_resize_volume()' will propagate this change
* to the flash.
*/
ubi->vtbl[vol_id].flags &= ~UBI_VTBL_AUTORESIZE_FLG;
Expand All @@ -655,7 +699,7 @@ static int autoresize(struct ubi_device *ubi, int vol_id)
struct ubi_vtbl_record vtbl_rec;

/*
* No avalilable PEBs to re-size the volume, clear the flag on
* No available PEBs to re-size the volume, clear the flag on
* flash and exit.
*/
memcpy(&vtbl_rec, &ubi->vtbl[vol_id],
Expand All @@ -682,13 +726,13 @@ static int autoresize(struct ubi_device *ubi, int vol_id)

/**
* ubi_attach_mtd_dev - attach an MTD device.
* @mtd_dev: MTD device description object
* @mtd: MTD device description object
* @ubi_num: number to assign to the new UBI device
* @vid_hdr_offset: VID header offset
*
* This function attaches MTD device @mtd_dev to UBI and assign @ubi_num number
* to the newly created UBI device, unless @ubi_num is %UBI_DEV_NUM_AUTO, in
* which case this function finds a vacant device nubert and assings it
* which case this function finds a vacant device number and assigns it
* automatically. Returns the new UBI device number in case of success and a
* negative error code in case of failure.
*
Expand All @@ -698,7 +742,7 @@ static int autoresize(struct ubi_device *ubi, int vol_id)
int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, int vid_hdr_offset)
{
struct ubi_device *ubi;
int i, err;
int i, err, do_free = 1;

/*
* Check if we already have the same MTD device attached.
Expand Down Expand Up @@ -735,7 +779,8 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, int vid_hdr_offset)
if (!ubi_devices[ubi_num])
break;
if (ubi_num == UBI_MAX_DEVICES) {
dbg_err("only %d UBI devices may be created", UBI_MAX_DEVICES);
dbg_err("only %d UBI devices may be created",
UBI_MAX_DEVICES);
return -ENFILE;
}
} else {
Expand All @@ -760,6 +805,7 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, int vid_hdr_offset)

mutex_init(&ubi->buf_mutex);
mutex_init(&ubi->ckvol_mutex);
mutex_init(&ubi->mult_mutex);
mutex_init(&ubi->volumes_mutex);
spin_lock_init(&ubi->volumes_lock);

Expand Down Expand Up @@ -798,7 +844,7 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, int vid_hdr_offset)

err = uif_init(ubi);
if (err)
goto out_detach;
goto out_nofree;

ubi->bgt_thread = kthread_create(ubi_thread, ubi, ubi->bgt_name);
if (IS_ERR(ubi->bgt_thread)) {
Expand All @@ -824,20 +870,22 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, int vid_hdr_offset)
ubi->beb_rsvd_pebs);
ubi_msg("max/mean erase counter: %d/%d", ubi->max_ec, ubi->mean_ec);

/* Enable the background thread */
if (!DBG_DISABLE_BGT) {
if (!DBG_DISABLE_BGT)
ubi->thread_enabled = 1;
wake_up_process(ubi->bgt_thread);
}
wake_up_process(ubi->bgt_thread);

ubi_devices[ubi_num] = ubi;
return ubi_num;

out_uif:
uif_close(ubi);
out_nofree:
do_free = 0;
out_detach:
ubi_eba_close(ubi);
ubi_wl_close(ubi);
if (do_free)
free_user_volumes(ubi);
free_internal_volumes(ubi);
vfree(ubi->vtbl);
out_free:
vfree(ubi->peb_buf1);
Expand Down Expand Up @@ -899,8 +947,8 @@ int ubi_detach_mtd_dev(int ubi_num, int anyway)
kthread_stop(ubi->bgt_thread);

uif_close(ubi);
ubi_eba_close(ubi);
ubi_wl_close(ubi);
free_internal_volumes(ubi);
vfree(ubi->vtbl);
put_mtd_device(ubi->mtd);
vfree(ubi->peb_buf1);
Expand Down Expand Up @@ -1044,8 +1092,7 @@ static void __exit ubi_exit(void)
module_exit(ubi_exit);

/**
* bytes_str_to_int - convert a string representing number of bytes to an
* integer.
* bytes_str_to_int - convert a number of bytes string into an integer.
* @str: the string to convert
*
* This function returns positive resulting integer in case of success and a
Expand Down
Loading

0 comments on commit 996abf0

Please sign in to comment.