Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 305191
b: refs/heads/master
c: 62f3845
h: refs/heads/master
i:
  305189: b19d6dd
  305187: c18e0e3
  305183: 6b99f65
v: v3
  • Loading branch information
Joel Reardon authored and Artem Bityutskiy committed May 21, 2012
1 parent 88f1b19 commit 677faf9
Show file tree
Hide file tree
Showing 8 changed files with 71 additions and 32 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 05a3cb7dcec5a15ed9b18a5317ba2075355c7547
refs/heads/master: 62f384552b6756cf1ea71f8762d1e97dc77dbd90
2 changes: 1 addition & 1 deletion trunk/drivers/mtd/ubi/cdev.c
Original file line number Diff line number Diff line change
Expand Up @@ -514,7 +514,7 @@ static long vol_cdev_ioctl(struct file *file, unsigned int cmd,
if (err)
break;

err = ubi_wl_flush(ubi);
err = ubi_wl_flush(ubi, UBI_ALL, UBI_ALL);
break;
}

Expand Down
29 changes: 28 additions & 1 deletion trunk/drivers/mtd/ubi/kapi.c
Original file line number Diff line number Diff line change
Expand Up @@ -551,7 +551,7 @@ int ubi_leb_erase(struct ubi_volume_desc *desc, int lnum)
if (err)
return err;

return ubi_wl_flush(ubi);
return ubi_wl_flush(ubi, vol->vol_id, lnum);
}
EXPORT_SYMBOL_GPL(ubi_leb_erase);

Expand Down Expand Up @@ -704,6 +704,33 @@ int ubi_sync(int ubi_num)
}
EXPORT_SYMBOL_GPL(ubi_sync);

/**
* ubi_flush - flush UBI work queue.
* @ubi_num: UBI device to flush work queue
* @vol_id: volume id to flush for
* @lnum: logical eraseblock number to flush for
*
* This function executes all pending works for a particular volume id / logical
* eraseblock number pair. If either value is set to %UBI_ALL, then it acts as
* a wildcard for all of the corresponding volume numbers or logical
* eraseblock numbers. It returns zero in case of success and a negative error
* code in case of failure.
*/
int ubi_flush(int ubi_num, int vol_id, int lnum)
{
struct ubi_device *ubi;
int err = 0;

ubi = ubi_get_device(ubi_num);
if (!ubi)
return -ENODEV;

err = ubi_wl_flush(ubi, vol_id, lnum);
ubi_put_device(ubi);
return err;
}
EXPORT_SYMBOL_GPL(ubi_flush);

BLOCKING_NOTIFIER_HEAD(ubi_notifiers);

/**
Expand Down
2 changes: 1 addition & 1 deletion trunk/drivers/mtd/ubi/ubi.h
Original file line number Diff line number Diff line change
Expand Up @@ -669,7 +669,7 @@ int ubi_eba_init(struct ubi_device *ubi, struct ubi_attach_info *ai);
int ubi_wl_get_peb(struct ubi_device *ubi);
int ubi_wl_put_peb(struct ubi_device *ubi, int vol_id, int lnum,
int pnum, int torture);
int ubi_wl_flush(struct ubi_device *ubi);
int ubi_wl_flush(struct ubi_device *ubi, int vol_id, int lnum);
int ubi_wl_scrub_peb(struct ubi_device *ubi, int pnum);
int ubi_wl_init(struct ubi_device *ubi, struct ubi_attach_info *ai);
void ubi_wl_close(struct ubi_device *ubi);
Expand Down
4 changes: 2 additions & 2 deletions trunk/drivers/mtd/ubi/upd.c
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ int ubi_start_update(struct ubi_device *ubi, struct ubi_volume *vol,
}

if (bytes == 0) {
err = ubi_wl_flush(ubi);
err = ubi_wl_flush(ubi, UBI_ALL, UBI_ALL);
if (err)
return err;

Expand Down Expand Up @@ -361,7 +361,7 @@ int ubi_more_update_data(struct ubi_device *ubi, struct ubi_volume *vol,

ubi_assert(vol->upd_received <= vol->upd_bytes);
if (vol->upd_received == vol->upd_bytes) {
err = ubi_wl_flush(ubi);
err = ubi_wl_flush(ubi, UBI_ALL, UBI_ALL);
if (err)
return err;
/* The update is finished, clear the update marker */
Expand Down
2 changes: 1 addition & 1 deletion trunk/drivers/mtd/ubi/vmt.c
Original file line number Diff line number Diff line change
Expand Up @@ -280,7 +280,7 @@ int ubi_create_volume(struct ubi_device *ubi, struct ubi_mkvol_req *req)
* Finish all pending erases because there may be some LEBs belonging
* to the same volume ID.
*/
err = ubi_wl_flush(ubi);
err = ubi_wl_flush(ubi, vol_id, UBI_ALL);
if (err)
goto out_acc;

Expand Down
61 changes: 36 additions & 25 deletions trunk/drivers/mtd/ubi/wl.c
Original file line number Diff line number Diff line change
Expand Up @@ -1241,44 +1241,55 @@ int ubi_wl_scrub_peb(struct ubi_device *ubi, int pnum)
/**
* ubi_wl_flush - flush all pending works.
* @ubi: UBI device description object
* @vol_id: the volume id to flush for
* @lnum: the logical eraseblock number to flush for
*
* This function returns zero in case of success and a negative error code in
* case of failure.
* This function executes all pending works for a particular volume id /
* logical eraseblock number pair. If either value is set to %UBI_ALL, then it
* acts as a wildcard for all of the corresponding volume numbers or logical
* eraseblock numbers. It returns zero in case of success and a negative error
* code in case of failure.
*/
int ubi_wl_flush(struct ubi_device *ubi)
int ubi_wl_flush(struct ubi_device *ubi, int vol_id, int lnum)
{
int err;
int err = 0;
int found = 1;

/*
* Erase while the pending works queue is not empty, but not more than
* the number of currently pending works.
*/
dbg_wl("flush (%d pending works)", ubi->works_count);
while (ubi->works_count) {
err = do_work(ubi);
if (err)
return err;
}
dbg_wl("flush pending work for LEB %d:%d (%d pending works)",
vol_id, lnum, ubi->works_count);

/*
* Make sure all the works which have been done in parallel are
* finished.
*/
down_write(&ubi->work_sem);
up_write(&ubi->work_sem);
while (found) {
struct ubi_work *wrk;
found = 0;

/*
* And in case last was the WL worker and it canceled the LEB
* movement, flush again.
*/
while (ubi->works_count) {
dbg_wl("flush more (%d pending works)", ubi->works_count);
err = do_work(ubi);
if (err)
return err;
spin_lock(&ubi->wl_lock);
list_for_each_entry(wrk, &ubi->works, list) {
if ((vol_id == UBI_ALL || wrk->vol_id == vol_id) &&
(lnum == UBI_ALL || wrk->lnum == lnum)) {
list_del(&wrk->list);
ubi->works_count -= 1;
ubi_assert(ubi->works_count >= 0);
spin_unlock(&ubi->wl_lock);

err = wrk->func(ubi, wrk, 0);
if (err)
goto out;
spin_lock(&ubi->wl_lock);
found = 1;
break;
}
}
spin_unlock(&ubi->wl_lock);
}

return 0;
out:
up_write(&ubi->work_sem);
return err;
}

/**
Expand Down
1 change: 1 addition & 0 deletions trunk/include/linux/mtd/ubi.h
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,7 @@ int ubi_leb_unmap(struct ubi_volume_desc *desc, int lnum);
int ubi_leb_map(struct ubi_volume_desc *desc, int lnum);
int ubi_is_mapped(struct ubi_volume_desc *desc, int lnum);
int ubi_sync(int ubi_num);
int ubi_flush(int ubi_num, int vol_id, int lnum);

/*
* This function is the same as the 'ubi_leb_read()' function, but it does not
Expand Down

0 comments on commit 677faf9

Please sign in to comment.