Skip to content

Commit 350130a

Browse files
committed
Merge tag 'ubifs-for-linus-6.14-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rw/ubifs
Pull UBI and UBIFS updates from Richard Weinberger: "UBI: - New interface to dump detailed erase counters - Fixes around wear-leveling UBIFS: - Minor cleanups - Fix for TNC dumping code" * tag 'ubifs-for-linus-6.14-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rw/ubifs: ubi: ubi_get_ec_info: Fix compiling error 'cast specifies array type' ubi: Implement ioctl for detailed erase counters ubi: Expose interface for detailed erase counters ubifs: skip dumping tnc tree when zroot is null ubi: Revert "ubi: wl: Close down wear-leveling before nand is suspended" ubifs: ubifs_dump_leb: remove return from end of void function ubifs: dump_lpt_leb: remove return at end of void function ubi: Add a check for ubi_num
2 parents 2a9f04b + 69146a8 commit 350130a

File tree

7 files changed

+117
-35
lines changed

7 files changed

+117
-35
lines changed

drivers/mtd/ubi/build.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1537,7 +1537,7 @@ static int ubi_mtd_param_parse(const char *val, const struct kernel_param *kp)
15371537
if (token) {
15381538
int err = kstrtoint(token, 10, &p->ubi_num);
15391539

1540-
if (err) {
1540+
if (err || p->ubi_num < UBI_DEV_NUM_AUTO) {
15411541
pr_err("UBI error: bad value for ubi_num parameter: %s\n",
15421542
token);
15431543
return -EINVAL;

drivers/mtd/ubi/cdev.c

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -828,6 +828,70 @@ static int rename_volumes(struct ubi_device *ubi,
828828
return err;
829829
}
830830

831+
static int ubi_get_ec_info(struct ubi_device *ubi, struct ubi_ecinfo_req __user *ureq)
832+
{
833+
struct ubi_ecinfo_req req;
834+
struct ubi_wl_entry *wl;
835+
int read_cnt;
836+
int peb;
837+
int end_peb;
838+
839+
/* Copy the input arguments */
840+
if (copy_from_user(&req, ureq, sizeof(struct ubi_ecinfo_req)))
841+
return -EFAULT;
842+
843+
/* Check input arguments */
844+
if (req.length <= 0 || req.start < 0 || req.start >= ubi->peb_count)
845+
return -EINVAL;
846+
847+
if (check_add_overflow(req.start, req.length, &end_peb))
848+
return -EINVAL;
849+
850+
if (end_peb > ubi->peb_count)
851+
end_peb = ubi->peb_count;
852+
853+
/* Check access rights before filling erase_counters array */
854+
if (!access_ok((void __user *)ureq->erase_counters,
855+
(end_peb-req.start) * sizeof(int32_t)))
856+
return -EFAULT;
857+
858+
/* Fill erase counter array */
859+
read_cnt = 0;
860+
for (peb = req.start; peb < end_peb; read_cnt++, peb++) {
861+
int ec;
862+
863+
if (ubi_io_is_bad(ubi, peb)) {
864+
if (__put_user(UBI_UNKNOWN, ureq->erase_counters+read_cnt))
865+
return -EFAULT;
866+
867+
continue;
868+
}
869+
870+
spin_lock(&ubi->wl_lock);
871+
872+
wl = ubi->lookuptbl[peb];
873+
if (wl)
874+
ec = wl->ec;
875+
else
876+
ec = UBI_UNKNOWN;
877+
878+
spin_unlock(&ubi->wl_lock);
879+
880+
if (__put_user(ec, ureq->erase_counters+read_cnt))
881+
return -EFAULT;
882+
883+
}
884+
885+
/* Return actual read length */
886+
req.read_length = read_cnt;
887+
888+
/* Copy everything except erase counter array */
889+
if (copy_to_user(ureq, &req, sizeof(struct ubi_ecinfo_req)))
890+
return -EFAULT;
891+
892+
return 0;
893+
}
894+
831895
static long ubi_cdev_ioctl(struct file *file, unsigned int cmd,
832896
unsigned long arg)
833897
{
@@ -991,6 +1055,12 @@ static long ubi_cdev_ioctl(struct file *file, unsigned int cmd,
9911055
break;
9921056
}
9931057

1058+
case UBI_IOCECNFO:
1059+
{
1060+
err = ubi_get_ec_info(ubi, argp);
1061+
break;
1062+
}
1063+
9941064
default:
9951065
err = -ENOTTY;
9961066
break;

drivers/mtd/ubi/ubi.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -549,7 +549,6 @@ struct ubi_debug_info {
549549
* @peb_buf: a buffer of PEB size used for different purposes
550550
* @buf_mutex: protects @peb_buf
551551
* @ckvol_mutex: serializes static volume checking when opening
552-
* @wl_reboot_notifier: close all wear-leveling work before reboot
553552
*
554553
* @dbg: debugging information for this UBI device
555554
*/
@@ -652,7 +651,6 @@ struct ubi_device {
652651
void *peb_buf;
653652
struct mutex buf_mutex;
654653
struct mutex ckvol_mutex;
655-
struct notifier_block wl_reboot_notifier;
656654

657655
struct ubi_debug_info dbg;
658656
};

drivers/mtd/ubi/wl.c

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,6 @@
8989
#include <linux/crc32.h>
9090
#include <linux/freezer.h>
9191
#include <linux/kthread.h>
92-
#include <linux/reboot.h>
9392
#include "ubi.h"
9493
#include "wl.h"
9594

@@ -128,8 +127,6 @@ static int self_check_in_wl_tree(const struct ubi_device *ubi,
128127
struct ubi_wl_entry *e, struct rb_root *root);
129128
static int self_check_in_pq(const struct ubi_device *ubi,
130129
struct ubi_wl_entry *e);
131-
static int ubi_wl_reboot_notifier(struct notifier_block *n,
132-
unsigned long state, void *cmd);
133130

134131
/**
135132
* wl_tree_add - add a wear-leveling entry to a WL RB-tree.
@@ -1953,13 +1950,6 @@ int ubi_wl_init(struct ubi_device *ubi, struct ubi_attach_info *ai)
19531950
if (!ubi->ro_mode && !ubi->fm_disabled)
19541951
ubi_ensure_anchor_pebs(ubi);
19551952
#endif
1956-
1957-
if (!ubi->wl_reboot_notifier.notifier_call) {
1958-
ubi->wl_reboot_notifier.notifier_call = ubi_wl_reboot_notifier;
1959-
ubi->wl_reboot_notifier.priority = 1; /* Higher than MTD */
1960-
register_reboot_notifier(&ubi->wl_reboot_notifier);
1961-
}
1962-
19631953
return 0;
19641954

19651955
out_free:
@@ -2005,17 +1995,6 @@ void ubi_wl_close(struct ubi_device *ubi)
20051995
kfree(ubi->lookuptbl);
20061996
}
20071997

2008-
static int ubi_wl_reboot_notifier(struct notifier_block *n,
2009-
unsigned long state, void *cmd)
2010-
{
2011-
struct ubi_device *ubi;
2012-
2013-
ubi = container_of(n, struct ubi_device, wl_reboot_notifier);
2014-
ubi_wl_close(ubi);
2015-
2016-
return NOTIFY_DONE;
2017-
}
2018-
20191998
/**
20201999
* self_check_ec - make sure that the erase counter of a PEB is correct.
20212000
* @ubi: UBI device description object

fs/ubifs/debug.c

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -863,7 +863,6 @@ void ubifs_dump_leb(const struct ubifs_info *c, int lnum)
863863

864864
out:
865865
vfree(buf);
866-
return;
867866
}
868867

869868
void ubifs_dump_znode(const struct ubifs_info *c,
@@ -946,16 +945,20 @@ void ubifs_dump_tnc(struct ubifs_info *c)
946945

947946
pr_err("\n");
948947
pr_err("(pid %d) start dumping TNC tree\n", current->pid);
949-
znode = ubifs_tnc_levelorder_next(c, c->zroot.znode, NULL);
950-
level = znode->level;
951-
pr_err("== Level %d ==\n", level);
952-
while (znode) {
953-
if (level != znode->level) {
954-
level = znode->level;
955-
pr_err("== Level %d ==\n", level);
948+
if (c->zroot.znode) {
949+
znode = ubifs_tnc_levelorder_next(c, c->zroot.znode, NULL);
950+
level = znode->level;
951+
pr_err("== Level %d ==\n", level);
952+
while (znode) {
953+
if (level != znode->level) {
954+
level = znode->level;
955+
pr_err("== Level %d ==\n", level);
956+
}
957+
ubifs_dump_znode(c, znode);
958+
znode = ubifs_tnc_levelorder_next(c, c->zroot.znode, znode);
956959
}
957-
ubifs_dump_znode(c, znode);
958-
znode = ubifs_tnc_levelorder_next(c, c->zroot.znode, znode);
960+
} else {
961+
pr_err("empty TNC tree in memory\n");
959962
}
960963
pr_err("(pid %d) finish dumping TNC tree\n", current->pid);
961964
}

fs/ubifs/lpt_commit.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1932,7 +1932,6 @@ static void dump_lpt_leb(const struct ubifs_info *c, int lnum)
19321932
pr_err("(pid %d) finish dumping LEB %d\n", current->pid, lnum);
19331933
out:
19341934
vfree(buf);
1935-
return;
19361935
}
19371936

19381937
/**

include/uapi/mtd/ubi-user.h

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,8 @@
175175
#define UBI_IOCRPEB _IOW(UBI_IOC_MAGIC, 4, __s32)
176176
/* Force scrubbing on the specified PEB */
177177
#define UBI_IOCSPEB _IOW(UBI_IOC_MAGIC, 5, __s32)
178+
/* Read detailed device erase counter information */
179+
#define UBI_IOCECNFO _IOWR(UBI_IOC_MAGIC, 6, struct ubi_ecinfo_req)
178180

179181
/* ioctl commands of the UBI control character device */
180182

@@ -412,6 +414,37 @@ struct ubi_rnvol_req {
412414
} ents[UBI_MAX_RNVOL];
413415
} __packed;
414416

417+
/**
418+
* struct ubi_ecinfo_req - a data structure used for requesting and receiving
419+
* erase block counter information from a UBI device.
420+
*
421+
* @start: index of first physical erase block to read (in)
422+
* @length: number of erase counters to read (in)
423+
* @read_length: number of erase counters that was actually read (out)
424+
* @padding: reserved for future, not used, has to be zeroed
425+
* @erase_counters: array of erase counter values (out)
426+
*
427+
* This structure is used to retrieve erase counter information for a specified
428+
* range of PEBs on a UBI device.
429+
* Erase counters are read from @start and attempts to read @length number of
430+
* erase counters.
431+
* The retrieved values are stored in the @erase_counters array. It is the
432+
* responsibility of the caller to allocate enough memory for storing @length
433+
* elements in the @erase_counters array.
434+
* If a block is bad or if the erase counter is unknown the corresponding value
435+
* in the array will be set to -1.
436+
* The @read_length field will indicate the number of erase counters actually
437+
* read. Typically @read_length will be limited due to memory or the number of
438+
* PEBs on the UBI device.
439+
*/
440+
struct ubi_ecinfo_req {
441+
__s32 start;
442+
__s32 length;
443+
__s32 read_length;
444+
__s8 padding[16];
445+
__s32 erase_counters[];
446+
} __packed;
447+
415448
/**
416449
* struct ubi_leb_change_req - a data structure used in atomic LEB change
417450
* requests.

0 commit comments

Comments
 (0)