* [PATCH 00/30] UBIFS: latest patches
@ 2011-06-09 9:04 Artem Bityutskiy
2011-06-09 9:04 ` [PATCH 01/30] UBIFS: return EROFS in case of broken commit Artem Bityutskiy
` (29 more replies)
0 siblings, 30 replies; 31+ messages in thread
From: Artem Bityutskiy @ 2011-06-09 9:04 UTC (permalink / raw)
To: linux-mtd
From: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
Hi,
here are latest UBIFS patches. Most of them are about cleaning up debugging
stuff and switching to debugfs knobs.
Artem.
^ permalink raw reply [flat|nested] 31+ messages in thread
* [PATCH 01/30] UBIFS: return EROFS in case of broken commit
2011-06-09 9:04 [PATCH 00/30] UBIFS: latest patches Artem Bityutskiy
@ 2011-06-09 9:04 ` Artem Bityutskiy
2011-06-09 9:04 ` [PATCH 02/30] UBIFS: lessen the size of debugging info data structure Artem Bityutskiy
` (28 subsequent siblings)
29 siblings, 0 replies; 31+ messages in thread
From: Artem Bityutskiy @ 2011-06-09 9:04 UTC (permalink / raw)
To: linux-mtd
From: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
If commit failed and it is in broken state, UBIFS switches to R/O mode. Most
operations return -EROFS in this case, except of commit which returns -EINVAL.
Make it return -EROFS too for consistency. This is also important for our power
cut emulation testing.
Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
---
fs/ubifs/commit.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/fs/ubifs/commit.c b/fs/ubifs/commit.c
index 87cd0ea..8ab03d1 100644
--- a/fs/ubifs/commit.c
+++ b/fs/ubifs/commit.c
@@ -418,7 +418,7 @@ int ubifs_run_commit(struct ubifs_info *c)
spin_lock(&c->cs_lock);
if (c->cmt_state == COMMIT_BROKEN) {
- err = -EINVAL;
+ err = -EROFS;
goto out;
}
@@ -444,7 +444,7 @@ int ubifs_run_commit(struct ubifs_info *c)
* re-check it.
*/
if (c->cmt_state == COMMIT_BROKEN) {
- err = -EINVAL;
+ err = -EROFS;
goto out_cmt_unlock;
}
--
1.7.2.3
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [PATCH 02/30] UBIFS: lessen the size of debugging info data structure
2011-06-09 9:04 [PATCH 00/30] UBIFS: latest patches Artem Bityutskiy
2011-06-09 9:04 ` [PATCH 01/30] UBIFS: return EROFS in case of broken commit Artem Bityutskiy
@ 2011-06-09 9:04 ` Artem Bityutskiy
2011-06-09 9:04 ` [PATCH 03/30] UBIFS: dump stack when pnode or nnode reading fails Artem Bityutskiy
` (27 subsequent siblings)
29 siblings, 0 replies; 31+ messages in thread
From: Artem Bityutskiy @ 2011-06-09 9:04 UTC (permalink / raw)
To: linux-mtd
From: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
This patch lessens the 'struct ubifs_debug_info' size by 90 bytes by
allocating less bytes for the debugfs root directory name. It introduces macros
for the name patter an length instead of hard-coding 100 bytes. It also makes
UBIFS use 'snprintf()' and teaches it to gracefully catch situations when the
name array is too short.
Additionally, this patch makes 2 unrelated changes - I just thought they do not
deserve separate commits: simplifies 'ubifs_assert()' for non-debugging case
and makes 'dbg_debugfs_init()' properly verify debugfs return code which may be
an error code or NULL, so we should you 'IS_ERR_OR_NULL()' instead of
'IS_ERR()'.
Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
---
fs/ubifs/debug.c | 18 +++++++++++++-----
fs/ubifs/debug.h | 11 +++++++++--
2 files changed, 22 insertions(+), 7 deletions(-)
diff --git a/fs/ubifs/debug.c b/fs/ubifs/debug.c
index 0bb2bce..c9609a6 100644
--- a/fs/ubifs/debug.c
+++ b/fs/ubifs/debug.c
@@ -2815,8 +2815,8 @@ static struct dentry *dfs_rootdir;
int dbg_debugfs_init(void)
{
dfs_rootdir = debugfs_create_dir("ubifs", NULL);
- if (IS_ERR(dfs_rootdir)) {
- int err = PTR_ERR(dfs_rootdir);
+ if (IS_ERR_OR_NULL(dfs_rootdir)) {
+ int err = dfs_rootdir ? PTR_ERR(dfs_rootdir) : -ENODEV;
ubifs_err("cannot create \"ubifs\" debugfs directory, "
"error %d\n", err);
return err;
@@ -2880,12 +2880,20 @@ static const struct file_operations dfs_fops = {
*/
int dbg_debugfs_init_fs(struct ubifs_info *c)
{
- int err;
+ int err, n;
const char *fname;
struct dentry *dent;
struct ubifs_debug_info *d = c->dbg;
- sprintf(d->dfs_dir_name, "ubi%d_%d", c->vi.ubi_num, c->vi.vol_id);
+ n = snprintf(d->dfs_dir_name, UBIFS_DFS_DIR_LEN + 1, UBIFS_DFS_DIR_NAME,
+ c->vi.ubi_num, c->vi.vol_id);
+ if (n == UBIFS_DFS_DIR_LEN) {
+ /* The array size is too small */
+ fname = UBIFS_DFS_DIR_NAME;
+ dent = ERR_PTR(-EINVAL);
+ goto out;
+ }
+
fname = d->dfs_dir_name;
dent = debugfs_create_dir(fname, dfs_rootdir);
if (IS_ERR_OR_NULL(dent))
@@ -2916,7 +2924,7 @@ out_remove:
debugfs_remove_recursive(d->dfs_dir);
out:
err = dent ? PTR_ERR(dent) : -ENODEV;
- ubifs_err("cannot create \"%s\" debugfs directory, error %d\n",
+ ubifs_err("cannot create \"%s\" debugfs filr or directory, error %d\n",
fname, err);
return err;
}
diff --git a/fs/ubifs/debug.h b/fs/ubifs/debug.h
index a811ac4..b59c43a 100644
--- a/fs/ubifs/debug.h
+++ b/fs/ubifs/debug.h
@@ -33,6 +33,13 @@ typedef int (*dbg_znode_callback)(struct ubifs_info *c,
#include <linux/random.h>
+/*
+ * The UBIFS debugfs directory name pattern and maximum name length (3 for "ubi"
+ * + 1 for "_" and plus 2x2 for 2 UBI numbers and 1 for the trailing zero byte.
+ */
+#define UBIFS_DFS_DIR_NAME "ubi%d_%d"
+#define UBIFS_DFS_DIR_LEN (3 + 1 + 2*2 + 1)
+
/**
* ubifs_debug_info - per-FS debugging information.
* @old_zroot: old index root - used by 'dbg_check_old_index()'
@@ -84,7 +91,7 @@ struct ubifs_debug_info {
long long saved_free;
int saved_idx_gc_cnt;
- char dfs_dir_name[100];
+ char dfs_dir_name[UBIFS_DFS_DIR_LEN + 1];
struct dentry *dfs_dir;
struct dentry *dfs_dump_lprops;
struct dentry *dfs_dump_budg;
@@ -313,7 +320,7 @@ void dbg_debugfs_exit_fs(struct ubifs_info *c);
/* Use "if (0)" to make compiler check arguments even if debugging is off */
#define ubifs_assert(expr) do { \
- if (0 && (expr)) \
+ if (0) \
printk(KERN_CRIT "UBIFS assert failed in %s at %u (pid %d)\n", \
__func__, __LINE__, current->pid); \
} while (0)
--
1.7.2.3
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [PATCH 03/30] UBIFS: dump stack when pnode or nnode reading fails
2011-06-09 9:04 [PATCH 00/30] UBIFS: latest patches Artem Bityutskiy
2011-06-09 9:04 ` [PATCH 01/30] UBIFS: return EROFS in case of broken commit Artem Bityutskiy
2011-06-09 9:04 ` [PATCH 02/30] UBIFS: lessen the size of debugging info data structure Artem Bityutskiy
@ 2011-06-09 9:04 ` Artem Bityutskiy
2011-06-09 9:04 ` [PATCH 04/30] UBIFS: improve inode dumping function Artem Bityutskiy
` (26 subsequent siblings)
29 siblings, 0 replies; 31+ messages in thread
From: Artem Bityutskiy @ 2011-06-09 9:04 UTC (permalink / raw)
To: linux-mtd
From: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
When we fail to read a pnode or nnode - print stacktrace if debugging is enabled.
Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
---
fs/ubifs/lpt.c | 2 ++
1 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/fs/ubifs/lpt.c b/fs/ubifs/lpt.c
index ef5155e..04713cd 100644
--- a/fs/ubifs/lpt.c
+++ b/fs/ubifs/lpt.c
@@ -1247,6 +1247,7 @@ int ubifs_read_nnode(struct ubifs_info *c, struct ubifs_nnode *parent, int iip)
out:
ubifs_err("error %d reading nnode at %d:%d", err, lnum, offs);
+ dbg_dump_stack();
kfree(nnode);
return err;
}
@@ -1312,6 +1313,7 @@ static int read_pnode(struct ubifs_info *c, struct ubifs_nnode *parent, int iip)
out:
ubifs_err("error %d reading pnode at %d:%d", err, lnum, offs);
dbg_dump_pnode(c, pnode, parent, iip);
+ dbg_dump_stack();
dbg_msg("calc num: %d", calc_pnode_num_from_parent(c, parent, iip));
kfree(pnode);
return err;
--
1.7.2.3
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [PATCH 04/30] UBIFS: improve inode dumping function
2011-06-09 9:04 [PATCH 00/30] UBIFS: latest patches Artem Bityutskiy
` (2 preceding siblings ...)
2011-06-09 9:04 ` [PATCH 03/30] UBIFS: dump stack when pnode or nnode reading fails Artem Bityutskiy
@ 2011-06-09 9:04 ` Artem Bityutskiy
2011-06-09 9:04 ` [PATCH 05/30] UBIFS: rename dbg_check_dir_size function Artem Bityutskiy
` (25 subsequent siblings)
29 siblings, 0 replies; 31+ messages in thread
From: Artem Bityutskiy @ 2011-06-09 9:04 UTC (permalink / raw)
To: linux-mtd
From: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
Teach 'dbg_dump_inode()' dump directory entries for directory inodes.
This requires few additional changes:
1. The 'c' argument of 'dbg_dump_inode()' cannot be const any more.
2. Users of 'dbg_dump_inode()' should not have 'tnc_mutex' locked.
Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
---
fs/ubifs/debug.c | 56 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
fs/ubifs/debug.h | 6 ++--
fs/ubifs/tnc.c | 3 +-
3 files changed, 60 insertions(+), 5 deletions(-)
diff --git a/fs/ubifs/debug.c b/fs/ubifs/debug.c
index c9609a6..4a2170d 100644
--- a/fs/ubifs/debug.c
+++ b/fs/ubifs/debug.c
@@ -91,6 +91,28 @@ static const char *get_key_type(int type)
}
}
+static const char *get_dent_type(int type)
+{
+ switch (type) {
+ case UBIFS_ITYPE_REG:
+ return "file";
+ case UBIFS_ITYPE_DIR:
+ return "dir";
+ case UBIFS_ITYPE_LNK:
+ return "symlink";
+ case UBIFS_ITYPE_BLK:
+ return "blkdev";
+ case UBIFS_ITYPE_CHR:
+ return "char dev";
+ case UBIFS_ITYPE_FIFO:
+ return "fifo";
+ case UBIFS_ITYPE_SOCK:
+ return "socket";
+ default:
+ return "unknown/invalid type";
+ }
+}
+
static void sprintf_key(const struct ubifs_info *c, const union ubifs_key *key,
char *buffer)
{
@@ -234,9 +256,13 @@ static void dump_ch(const struct ubifs_ch *ch)
printk(KERN_DEBUG "\tlen %u\n", le32_to_cpu(ch->len));
}
-void dbg_dump_inode(const struct ubifs_info *c, const struct inode *inode)
+void dbg_dump_inode(struct ubifs_info *c, const struct inode *inode)
{
const struct ubifs_inode *ui = ubifs_inode(inode);
+ struct qstr nm = { .name = NULL };
+ union ubifs_key key;
+ struct ubifs_dent_node *dent, *pdent = NULL;
+ int count = 2;
printk(KERN_DEBUG "Dump in-memory inode:");
printk(KERN_DEBUG "\tinode %lu\n", inode->i_ino);
@@ -270,6 +296,32 @@ void dbg_dump_inode(const struct ubifs_info *c, const struct inode *inode)
printk(KERN_DEBUG "\tlast_page_read %lu\n", ui->last_page_read);
printk(KERN_DEBUG "\tread_in_a_row %lu\n", ui->read_in_a_row);
printk(KERN_DEBUG "\tdata_len %d\n", ui->data_len);
+
+ if (!S_ISDIR(inode->i_mode))
+ return;
+
+ printk(KERN_DEBUG "List of directory entries:\n");
+ ubifs_assert(!mutex_is_locked(&c->tnc_mutex));
+
+ lowest_dent_key(c, &key, inode->i_ino);
+ while (1) {
+ dent = ubifs_tnc_next_ent(c, &key, &nm);
+ if (IS_ERR(dent)) {
+ if (PTR_ERR(dent) != -ENOENT)
+ printk(KERN_DEBUG "error %ld\n", PTR_ERR(dent));
+ break;
+ }
+
+ printk(KERN_DEBUG "\t%d: %s (%s)\n",
+ count++, dent->name, get_dent_type(dent->type));
+
+ nm.name = dent->name;
+ nm.len = le16_to_cpu(dent->nlen);
+ kfree(pdent);
+ pdent = dent;
+ key_read(c, &dent->key, &key);
+ }
+ kfree(pdent);
}
void dbg_dump_node(const struct ubifs_info *c, const void *node)
@@ -1167,12 +1219,14 @@ int dbg_check_dir_size(struct ubifs_info *c, const struct inode *dir)
"but calculated size is %llu", dir->i_ino,
(unsigned long long)i_size_read(dir),
(unsigned long long)size);
+ dbg_dump_inode(c, dir);
dump_stack();
return -EINVAL;
}
if (dir->i_nlink != nlink) {
ubifs_err("directory inode %lu has nlink %u, but calculated "
"nlink is %u", dir->i_ino, dir->i_nlink, nlink);
+ dbg_dump_inode(c, dir);
dump_stack();
return -EINVAL;
}
diff --git a/fs/ubifs/debug.h b/fs/ubifs/debug.h
index b59c43a..c6ad9ea 100644
--- a/fs/ubifs/debug.h
+++ b/fs/ubifs/debug.h
@@ -214,7 +214,7 @@ const char *dbg_cstate(int cmt_state);
const char *dbg_jhead(int jhead);
const char *dbg_get_key_dump(const struct ubifs_info *c,
const union ubifs_key *key);
-void dbg_dump_inode(const struct ubifs_info *c, const struct inode *inode);
+void dbg_dump_inode(struct ubifs_info *c, const struct inode *inode);
void dbg_dump_node(const struct ubifs_info *c, const void *node);
void dbg_dump_lpt_node(const struct ubifs_info *c, void *node, int lnum,
int offs);
@@ -364,7 +364,7 @@ static inline const char *dbg_jhead(int jhead) { return ""; }
static inline const char *
dbg_get_key_dump(const struct ubifs_info *c,
const union ubifs_key *key) { return ""; }
-static inline void dbg_dump_inode(const struct ubifs_info *c,
+static inline void dbg_dump_inode(struct ubifs_info *c,
const struct inode *inode) { return; }
static inline void dbg_dump_node(const struct ubifs_info *c,
const void *node) { return; }
@@ -418,7 +418,7 @@ static inline int dbg_chk_lpt_sz(struct ubifs_info *c,
int action, int len) { return 0; }
static inline int dbg_check_synced_i_size(struct inode *inode) { return 0; }
static inline int dbg_check_dir_size(struct ubifs_info *c,
- const struct inode *dir) { return 0; }
+ const struct inode *dir) { return 0; }
static inline int dbg_check_tnc(struct ubifs_info *c, int extra) { return 0; }
static inline int dbg_check_idx_size(struct ubifs_info *c,
long long idx_size) { return 0; }
diff --git a/fs/ubifs/tnc.c b/fs/ubifs/tnc.c
index 91b4213..48b6ee6 100644
--- a/fs/ubifs/tnc.c
+++ b/fs/ubifs/tnc.c
@@ -3337,9 +3337,10 @@ out_dump:
ubifs_err("inode %lu has size %lld, but there are data at offset %lld "
"(data key %s)", (unsigned long)inode->i_ino, size,
((loff_t)block) << UBIFS_BLOCK_SHIFT, DBGKEY(key));
+ mutex_unlock(&c->tnc_mutex);
dbg_dump_inode(c, inode);
dbg_dump_stack();
- err = -EINVAL;
+ return -EINVAL;
out_unlock:
mutex_unlock(&c->tnc_mutex);
--
1.7.2.3
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [PATCH 05/30] UBIFS: rename dbg_check_dir_size function
2011-06-09 9:04 [PATCH 00/30] UBIFS: latest patches Artem Bityutskiy
` (3 preceding siblings ...)
2011-06-09 9:04 ` [PATCH 04/30] UBIFS: improve inode dumping function Artem Bityutskiy
@ 2011-06-09 9:04 ` Artem Bityutskiy
2011-06-09 9:04 ` [PATCH 06/30] UBIFS: minor cleanup: use S_ISREG helper Artem Bityutskiy
` (24 subsequent siblings)
29 siblings, 0 replies; 31+ messages in thread
From: Artem Bityutskiy @ 2011-06-09 9:04 UTC (permalink / raw)
To: linux-mtd
From: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
Since this function is not only about size checking, rename it to
'dbg_check_dir()'.
Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
---
fs/ubifs/debug.c | 2 +-
fs/ubifs/debug.h | 4 ++--
fs/ubifs/super.c | 2 +-
3 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/fs/ubifs/debug.c b/fs/ubifs/debug.c
index 4a2170d..26d4c61 100644
--- a/fs/ubifs/debug.c
+++ b/fs/ubifs/debug.c
@@ -1177,7 +1177,7 @@ int dbg_check_synced_i_size(struct inode *inode)
* Note, it is good idea to make sure the @dir->i_mutex is locked before
* calling this function.
*/
-int dbg_check_dir_size(struct ubifs_info *c, const struct inode *dir)
+int dbg_check_dir(struct ubifs_info *c, const struct inode *dir)
{
unsigned int nlink = 2;
union ubifs_key key;
diff --git a/fs/ubifs/debug.h b/fs/ubifs/debug.h
index c6ad9ea..a51c20b 100644
--- a/fs/ubifs/debug.h
+++ b/fs/ubifs/debug.h
@@ -248,7 +248,7 @@ int dbg_check_ltab(struct ubifs_info *c);
int dbg_chk_lpt_free_spc(struct ubifs_info *c);
int dbg_chk_lpt_sz(struct ubifs_info *c, int action, int len);
int dbg_check_synced_i_size(struct inode *inode);
-int dbg_check_dir_size(struct ubifs_info *c, const struct inode *dir);
+int dbg_check_dir(struct ubifs_info *c, const struct inode *dir);
int dbg_check_tnc(struct ubifs_info *c, int extra);
int dbg_check_idx_size(struct ubifs_info *c, long long idx_size);
int dbg_check_filesystem(struct ubifs_info *c);
@@ -417,7 +417,7 @@ static inline int dbg_chk_lpt_free_spc(struct ubifs_info *c) { return 0; }
static inline int dbg_chk_lpt_sz(struct ubifs_info *c,
int action, int len) { return 0; }
static inline int dbg_check_synced_i_size(struct inode *inode) { return 0; }
-static inline int dbg_check_dir_size(struct ubifs_info *c,
+static inline int dbg_check_dir(struct ubifs_info *c,
const struct inode *dir) { return 0; }
static inline int dbg_check_tnc(struct ubifs_info *c, int extra) { return 0; }
static inline int dbg_check_idx_size(struct ubifs_info *c,
diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c
index b5aeb5a..55161c6 100644
--- a/fs/ubifs/super.c
+++ b/fs/ubifs/super.c
@@ -94,7 +94,7 @@ static int validate_inode(struct ubifs_info *c, const struct inode *inode)
ubifs_compr_name(ui->compr_type));
}
- err = dbg_check_dir_size(c, inode);
+ err = dbg_check_dir(c, inode);
return err;
}
--
1.7.2.3
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [PATCH 06/30] UBIFS: minor cleanup: use S_ISREG helper
2011-06-09 9:04 [PATCH 00/30] UBIFS: latest patches Artem Bityutskiy
` (4 preceding siblings ...)
2011-06-09 9:04 ` [PATCH 05/30] UBIFS: rename dbg_check_dir_size function Artem Bityutskiy
@ 2011-06-09 9:04 ` Artem Bityutskiy
2011-06-09 9:04 ` [PATCH 07/30] UBIFS: remove unnecessary brackets Artem Bityutskiy
` (23 subsequent siblings)
29 siblings, 0 replies; 31+ messages in thread
From: Artem Bityutskiy @ 2011-06-09 9:04 UTC (permalink / raw)
To: linux-mtd
From: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
Instead of using long "(inode->i_mode & S_IFMT) != S_IFREG" expression, use
shorted "!S_ISREG(inode->i_mode)".
Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
---
fs/ubifs/super.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c
index 55161c6..70e8c92 100644
--- a/fs/ubifs/super.c
+++ b/fs/ubifs/super.c
@@ -85,7 +85,7 @@ static int validate_inode(struct ubifs_info *c, const struct inode *inode)
if (ui->data_len < 0 || ui->data_len > UBIFS_MAX_INO_DATA)
return 4;
- if (ui->xattr && (inode->i_mode & S_IFMT) != S_IFREG)
+ if (ui->xattr && !S_ISREG(inode->i_mode))
return 5;
if (!ubifs_compr_present(ui->compr_type)) {
--
1.7.2.3
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [PATCH 07/30] UBIFS: remove unnecessary brackets
2011-06-09 9:04 [PATCH 00/30] UBIFS: latest patches Artem Bityutskiy
` (5 preceding siblings ...)
2011-06-09 9:04 ` [PATCH 06/30] UBIFS: minor cleanup: use S_ISREG helper Artem Bityutskiy
@ 2011-06-09 9:04 ` Artem Bityutskiy
2011-06-09 9:04 ` [PATCH 08/30] UBIFS: remove dead code Artem Bityutskiy
` (22 subsequent siblings)
29 siblings, 0 replies; 31+ messages in thread
From: Artem Bityutskiy @ 2011-06-09 9:04 UTC (permalink / raw)
To: linux-mtd
From: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
Remove unnecessary brackets in "inode->i_flags |= (S_NOCMTIME)" statement to
make the code not look silly.
Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
---
fs/ubifs/dir.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/fs/ubifs/dir.c b/fs/ubifs/dir.c
index ef5abd3..c6cbdd0 100644
--- a/fs/ubifs/dir.c
+++ b/fs/ubifs/dir.c
@@ -102,7 +102,7 @@ struct inode *ubifs_new_inode(struct ubifs_info *c, const struct inode *dir,
* UBIFS has to fully control "clean <-> dirty" transitions of inodes
* to make budgeting work.
*/
- inode->i_flags |= (S_NOCMTIME);
+ inode->i_flags |= S_NOCMTIME;
inode_init_owner(inode, dir, mode);
inode->i_mtime = inode->i_atime = inode->i_ctime =
--
1.7.2.3
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [PATCH 08/30] UBIFS: remove dead code
2011-06-09 9:04 [PATCH 00/30] UBIFS: latest patches Artem Bityutskiy
` (6 preceding siblings ...)
2011-06-09 9:04 ` [PATCH 07/30] UBIFS: remove unnecessary brackets Artem Bityutskiy
@ 2011-06-09 9:04 ` Artem Bityutskiy
2011-06-09 9:04 ` [PATCH 09/30] UBIFS: harmonize znode flag helpers Artem Bityutskiy
` (21 subsequent siblings)
29 siblings, 0 replies; 31+ messages in thread
From: Artem Bityutskiy @ 2011-06-09 9:04 UTC (permalink / raw)
To: linux-mtd
From: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
Remove dead pieces of code under "if (c->min_io_size == 1)" statement -
we never execute it because in UBIFS 'c->min_io_size' is always at least 8.
This are leftovers from old pre-mainline prototype.
Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
---
fs/ubifs/tnc_commit.c | 106 ++++++++++++++-----------------------------------
1 files changed, 30 insertions(+), 76 deletions(-)
diff --git a/fs/ubifs/tnc_commit.c b/fs/ubifs/tnc_commit.c
index 41920f3..8315387 100644
--- a/fs/ubifs/tnc_commit.c
+++ b/fs/ubifs/tnc_commit.c
@@ -491,25 +491,6 @@ static int layout_in_empty_space(struct ubifs_info *c)
else
next_len = ubifs_idx_node_sz(c, cnext->child_cnt);
- if (c->min_io_size == 1) {
- buf_offs += ALIGN(len, 8);
- if (next_len) {
- if (buf_offs + next_len <= c->leb_size)
- continue;
- err = ubifs_update_one_lp(c, lnum, 0,
- c->leb_size - buf_offs, 0, 0);
- if (err)
- return err;
- lnum = -1;
- continue;
- }
- err = ubifs_update_one_lp(c, lnum,
- c->leb_size - buf_offs, 0, 0, 0);
- if (err)
- return err;
- break;
- }
-
/* Update buffer positions */
wlen = used + len;
used += ALIGN(len, 8);
@@ -830,7 +811,7 @@ static int write_index(struct ubifs_info *c)
struct ubifs_idx_node *idx;
struct ubifs_znode *znode, *cnext;
int i, lnum, offs, len, next_len, buf_len, buf_offs, used;
- int avail, wlen, err, lnum_pos = 0;
+ int avail, wlen, err, lnum_pos = 0, blen, nxt_offs;
cnext = c->enext;
if (!cnext)
@@ -938,65 +919,38 @@ static int write_index(struct ubifs_info *c)
else
next_len = ubifs_idx_node_sz(c, cnext->child_cnt);
- if (c->min_io_size == 1) {
- /*
- * Write the prepared index node immediately if there is
- * no minimum IO size
- */
- err = ubifs_leb_write(c, lnum, c->cbuf, buf_offs,
- wlen, UBI_SHORTTERM);
- if (err)
- return err;
- buf_offs += ALIGN(wlen, 8);
- if (next_len) {
- used = 0;
- avail = buf_len;
- if (buf_offs + next_len > c->leb_size) {
- err = ubifs_update_one_lp(c, lnum,
- LPROPS_NC, 0, 0, LPROPS_TAKEN);
- if (err)
- return err;
- lnum = -1;
- }
+ nxt_offs = buf_offs + used + next_len;
+ if (next_len && nxt_offs <= c->leb_size) {
+ if (avail > 0)
continue;
- }
+ else
+ blen = buf_len;
} else {
- int blen, nxt_offs = buf_offs + used + next_len;
-
- if (next_len && nxt_offs <= c->leb_size) {
- if (avail > 0)
- continue;
- else
- blen = buf_len;
- } else {
- wlen = ALIGN(wlen, 8);
- blen = ALIGN(wlen, c->min_io_size);
- ubifs_pad(c, c->cbuf + wlen, blen - wlen);
- }
- /*
- * The buffer is full or there are no more znodes
- * to do
- */
- err = ubifs_leb_write(c, lnum, c->cbuf, buf_offs,
- blen, UBI_SHORTTERM);
- if (err)
- return err;
- buf_offs += blen;
- if (next_len) {
- if (nxt_offs > c->leb_size) {
- err = ubifs_update_one_lp(c, lnum,
- LPROPS_NC, 0, 0, LPROPS_TAKEN);
- if (err)
- return err;
- lnum = -1;
- }
- used -= blen;
- if (used < 0)
- used = 0;
- avail = buf_len - used;
- memmove(c->cbuf, c->cbuf + blen, used);
- continue;
+ wlen = ALIGN(wlen, 8);
+ blen = ALIGN(wlen, c->min_io_size);
+ ubifs_pad(c, c->cbuf + wlen, blen - wlen);
+ }
+
+ /* The buffer is full or there are no more znodes to do */
+ err = ubifs_leb_write(c, lnum, c->cbuf, buf_offs, blen,
+ UBI_SHORTTERM);
+ if (err)
+ return err;
+ buf_offs += blen;
+ if (next_len) {
+ if (nxt_offs > c->leb_size) {
+ err = ubifs_update_one_lp(c, lnum, LPROPS_NC, 0,
+ 0, LPROPS_TAKEN);
+ if (err)
+ return err;
+ lnum = -1;
}
+ used -= blen;
+ if (used < 0)
+ used = 0;
+ avail = buf_len - used;
+ memmove(c->cbuf, c->cbuf + blen, used);
+ continue;
}
break;
}
--
1.7.2.3
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [PATCH 09/30] UBIFS: harmonize znode flag helpers
2011-06-09 9:04 [PATCH 00/30] UBIFS: latest patches Artem Bityutskiy
` (7 preceding siblings ...)
2011-06-09 9:04 ` [PATCH 08/30] UBIFS: remove dead code Artem Bityutskiy
@ 2011-06-09 9:04 ` Artem Bityutskiy
2011-06-09 9:04 ` [PATCH 10/30] UBIFS: use correct flags in lprops Artem Bityutskiy
` (20 subsequent siblings)
29 siblings, 0 replies; 31+ messages in thread
From: Artem Bityutskiy @ 2011-06-09 9:04 UTC (permalink / raw)
To: linux-mtd
From: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
We have 3 znode flags: cow, obsolete, dirty. For the last flag we have a
'ubifs_zn_dirty()' helper function, but for the other 2 flags we use
'test_bit()' directly.
This patch makes the situation more consistent and introduces helpers for the
other 2 flags: 'ubifs_zn_cow()' and 'ubifs_zn_obsolete()'.
Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
---
fs/ubifs/commit.c | 2 +-
fs/ubifs/misc.h | 23 +++++++++++++++++++++++
fs/ubifs/tnc.c | 13 ++++++-------
fs/ubifs/tnc_commit.c | 8 ++++----
4 files changed, 34 insertions(+), 12 deletions(-)
diff --git a/fs/ubifs/commit.c b/fs/ubifs/commit.c
index 8ab03d1..637e076 100644
--- a/fs/ubifs/commit.c
+++ b/fs/ubifs/commit.c
@@ -78,7 +78,7 @@ static int nothing_to_commit(struct ubifs_info *c)
* If the root TNC node is dirty, we definitely have something to
* commit.
*/
- if (c->zroot.znode && test_bit(DIRTY_ZNODE, &c->zroot.znode->flags))
+ if (c->zroot.znode && ubifs_zn_dirty(c->zroot.znode))
return 0;
/*
diff --git a/fs/ubifs/misc.h b/fs/ubifs/misc.h
index 0b5296a..160cd90 100644
--- a/fs/ubifs/misc.h
+++ b/fs/ubifs/misc.h
@@ -39,6 +39,29 @@ static inline int ubifs_zn_dirty(const struct ubifs_znode *znode)
}
/**
+ * ubifs_zn_obsolete - check if znode is obsolete.
+ * @znode: znode to check
+ *
+ * This helper function returns %1 if @znode is obsolete and %0 otherwise.
+ */
+static inline int ubifs_zn_obsolete(const struct ubifs_znode *znode)
+{
+ return !!test_bit(OBSOLETE_ZNODE, &znode->flags);
+}
+
+/**
+ * ubifs_zn_cow - check if znode has to be copied on write.
+ * @znode: znode to check
+ *
+ * This helper function returns %1 if @znode is has COW flag set and %0
+ * otherwise.
+ */
+static inline int ubifs_zn_cow(const struct ubifs_znode *znode)
+{
+ return !!test_bit(COW_ZNODE, &znode->flags);
+}
+
+/**
* ubifs_wake_up_bgt - wake up background thread.
* @c: UBIFS file-system description object
*/
diff --git a/fs/ubifs/tnc.c b/fs/ubifs/tnc.c
index 48b6ee6..b32a537 100644
--- a/fs/ubifs/tnc.c
+++ b/fs/ubifs/tnc.c
@@ -223,7 +223,7 @@ static struct ubifs_znode *copy_znode(struct ubifs_info *c,
__set_bit(DIRTY_ZNODE, &zn->flags);
__clear_bit(COW_ZNODE, &zn->flags);
- ubifs_assert(!test_bit(OBSOLETE_ZNODE, &znode->flags));
+ ubifs_assert(!ubifs_zn_obsolete(znode));
__set_bit(OBSOLETE_ZNODE, &znode->flags);
if (znode->level != 0) {
@@ -271,7 +271,7 @@ static struct ubifs_znode *dirty_cow_znode(struct ubifs_info *c,
struct ubifs_znode *zn;
int err;
- if (!test_bit(COW_ZNODE, &znode->flags)) {
+ if (!ubifs_zn_cow(znode)) {
/* znode is not being committed */
if (!test_and_set_bit(DIRTY_ZNODE, &znode->flags)) {
atomic_long_inc(&c->dirty_zn_cnt);
@@ -2423,7 +2423,7 @@ static int tnc_delete(struct ubifs_info *c, struct ubifs_znode *znode, int n)
*/
do {
- ubifs_assert(!test_bit(OBSOLETE_ZNODE, &znode->flags));
+ ubifs_assert(!ubifs_zn_obsolete(znode));
ubifs_assert(ubifs_zn_dirty(znode));
zp = znode->parent;
@@ -2479,9 +2479,8 @@ static int tnc_delete(struct ubifs_info *c, struct ubifs_znode *znode, int n)
c->zroot.offs = zbr->offs;
c->zroot.len = zbr->len;
c->zroot.znode = znode;
- ubifs_assert(!test_bit(OBSOLETE_ZNODE,
- &zp->flags));
- ubifs_assert(test_bit(DIRTY_ZNODE, &zp->flags));
+ ubifs_assert(!ubifs_zn_obsolete(zp));
+ ubifs_assert(ubifs_zn_dirty(zp));
atomic_long_dec(&c->dirty_zn_cnt);
if (zp->cnext) {
@@ -2865,7 +2864,7 @@ static void tnc_destroy_cnext(struct ubifs_info *c)
struct ubifs_znode *znode = cnext;
cnext = cnext->cnext;
- if (test_bit(OBSOLETE_ZNODE, &znode->flags))
+ if (ubifs_zn_obsolete(znode))
kfree(znode);
} while (cnext && cnext != c->cnext);
}
diff --git a/fs/ubifs/tnc_commit.c b/fs/ubifs/tnc_commit.c
index 8315387..f50c3e5 100644
--- a/fs/ubifs/tnc_commit.c
+++ b/fs/ubifs/tnc_commit.c
@@ -87,7 +87,7 @@ static int make_idx_node(struct ubifs_info *c, struct ubifs_idx_node *idx,
atomic_long_dec(&c->dirty_zn_cnt);
ubifs_assert(ubifs_zn_dirty(znode));
- ubifs_assert(test_bit(COW_ZNODE, &znode->flags));
+ ubifs_assert(ubifs_zn_cow(znode));
__clear_bit(DIRTY_ZNODE, &znode->flags);
__clear_bit(COW_ZNODE, &znode->flags);
@@ -639,7 +639,7 @@ static int get_znodes_to_commit(struct ubifs_info *c)
}
cnt += 1;
while (1) {
- ubifs_assert(!test_bit(COW_ZNODE, &znode->flags));
+ ubifs_assert(!ubifs_zn_cow(znode));
__set_bit(COW_ZNODE, &znode->flags);
znode->alt = 0;
cnext = find_next_dirty(znode);
@@ -888,7 +888,7 @@ static int write_index(struct ubifs_info *c)
cnext = znode->cnext;
ubifs_assert(ubifs_zn_dirty(znode));
- ubifs_assert(test_bit(COW_ZNODE, &znode->flags));
+ ubifs_assert(ubifs_zn_cow(znode));
/*
* It is important that other threads should see %DIRTY_ZNODE
@@ -983,7 +983,7 @@ static void free_obsolete_znodes(struct ubifs_info *c)
do {
znode = cnext;
cnext = znode->cnext;
- if (test_bit(OBSOLETE_ZNODE, &znode->flags))
+ if (ubifs_zn_obsolete(znode))
kfree(znode);
else {
znode->cnext = NULL;
--
1.7.2.3
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [PATCH 10/30] UBIFS: use correct flags in lprops
2011-06-09 9:04 [PATCH 00/30] UBIFS: latest patches Artem Bityutskiy
` (8 preceding siblings ...)
2011-06-09 9:04 ` [PATCH 09/30] UBIFS: harmonize znode flag helpers Artem Bityutskiy
@ 2011-06-09 9:04 ` Artem Bityutskiy
2011-06-09 9:04 ` [PATCH 11/30] UBIFS: add few commentaries about TNC Artem Bityutskiy
` (19 subsequent siblings)
29 siblings, 0 replies; 31+ messages in thread
From: Artem Bityutskiy @ 2011-06-09 9:04 UTC (permalink / raw)
To: linux-mtd
From: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
The UBIFS lpt tree is in many aspects similar to the TNC tree, and we have
similar flags for these trees. And by mistake we use the COW_ZNODE flag for
LPT in some places, instead of the right flag COW_CNODE. And this works
only because these two constants have the same value.
This patch makes all the LPT code to use COW_CNODE and also changes COW_CNODE
constant value to make sure we do not misuse the flags any more.
Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
---
fs/ubifs/lprops.c | 2 +-
fs/ubifs/lpt_commit.c | 6 +++---
fs/ubifs/ubifs.h | 8 ++++----
3 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/fs/ubifs/lprops.c b/fs/ubifs/lprops.c
index 667884f..98b8e73 100644
--- a/fs/ubifs/lprops.c
+++ b/fs/ubifs/lprops.c
@@ -504,7 +504,7 @@ static int is_lprops_dirty(struct ubifs_info *c, struct ubifs_lprops *lprops)
pnode = (struct ubifs_pnode *)container_of(lprops - pos,
struct ubifs_pnode,
lprops[0]);
- return !test_bit(COW_ZNODE, &pnode->flags) &&
+ return !test_bit(COW_CNODE, &pnode->flags) &&
test_bit(DIRTY_CNODE, &pnode->flags);
}
diff --git a/fs/ubifs/lpt_commit.c b/fs/ubifs/lpt_commit.c
index dfcb574..254e8d3 100644
--- a/fs/ubifs/lpt_commit.c
+++ b/fs/ubifs/lpt_commit.c
@@ -116,8 +116,8 @@ static int get_cnodes_to_commit(struct ubifs_info *c)
return 0;
cnt += 1;
while (1) {
- ubifs_assert(!test_bit(COW_ZNODE, &cnode->flags));
- __set_bit(COW_ZNODE, &cnode->flags);
+ ubifs_assert(!test_bit(COW_CNODE, &cnode->flags));
+ __set_bit(COW_CNODE, &cnode->flags);
cnext = next_dirty_cnode(cnode);
if (!cnext) {
cnode->cnext = c->lpt_cnext;
@@ -465,7 +465,7 @@ static int write_cnodes(struct ubifs_info *c)
*/
clear_bit(DIRTY_CNODE, &cnode->flags);
smp_mb__before_clear_bit();
- clear_bit(COW_ZNODE, &cnode->flags);
+ clear_bit(COW_CNODE, &cnode->flags);
smp_mb__after_clear_bit();
offs += len;
dbg_chk_lpt_sz(c, 1, len);
diff --git a/fs/ubifs/ubifs.h b/fs/ubifs/ubifs.h
index f79983d..3304aad 100644
--- a/fs/ubifs/ubifs.h
+++ b/fs/ubifs/ubifs.h
@@ -230,14 +230,14 @@ enum {
* LPT cnode flag bits.
*
* DIRTY_CNODE: cnode is dirty
- * COW_CNODE: cnode is being committed and must be copied before writing
* OBSOLETE_CNODE: cnode is being committed and has been copied (or deleted),
- * so it can (and must) be freed when the commit is finished
+ * so it can (and must) be freed when the commit is finished
+ * COW_CNODE: cnode is being committed and must be copied before writing
*/
enum {
DIRTY_CNODE = 0,
- COW_CNODE = 1,
- OBSOLETE_CNODE = 2,
+ OBSOLETE_CNODE = 1,
+ COW_CNODE = 2,
};
/*
--
1.7.2.3
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [PATCH 11/30] UBIFS: add few commentaries about TNC
2011-06-09 9:04 [PATCH 00/30] UBIFS: latest patches Artem Bityutskiy
` (9 preceding siblings ...)
2011-06-09 9:04 ` [PATCH 10/30] UBIFS: use correct flags in lprops Artem Bityutskiy
@ 2011-06-09 9:04 ` Artem Bityutskiy
2011-06-09 9:04 ` [PATCH 12/30] UBIFS: amend debugging name check function prototype Artem Bityutskiy
` (18 subsequent siblings)
29 siblings, 0 replies; 31+ messages in thread
From: Artem Bityutskiy @ 2011-06-09 9:04 UTC (permalink / raw)
To: linux-mtd
From: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
Add a couple of comments - while looking into TNC I could not easily figure out
few facts, so it is a good idea to document them in the code.
Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
---
fs/ubifs/tnc_commit.c | 26 ++++++++++++++++++++++++++
1 files changed, 26 insertions(+), 0 deletions(-)
diff --git a/fs/ubifs/tnc_commit.c b/fs/ubifs/tnc_commit.c
index f50c3e5..d6fab1a 100644
--- a/fs/ubifs/tnc_commit.c
+++ b/fs/ubifs/tnc_commit.c
@@ -89,6 +89,10 @@ static int make_idx_node(struct ubifs_info *c, struct ubifs_idx_node *idx,
ubifs_assert(ubifs_zn_dirty(znode));
ubifs_assert(ubifs_zn_cow(znode));
+ /*
+ * Note, unlike 'write_index()' we do not add memory barriers here
+ * because this function is called with @c->tnc_mutex locked.
+ */
__clear_bit(DIRTY_ZNODE, &znode->flags);
__clear_bit(COW_ZNODE, &znode->flags);
@@ -903,6 +907,28 @@ static int write_index(struct ubifs_info *c)
clear_bit(COW_ZNODE, &znode->flags);
smp_mb__after_clear_bit();
+ /*
+ * We have marked the znode as clean but have not updated the
+ * @c->clean_zn_cnt counter. If this znode becomes dirty again
+ * before 'free_obsolete_znodes()' is called, then
+ * @c->clean_zn_cnt will be decremented before it gets
+ * incremented (resulting in 2 decrements for the same znode).
+ * This means that @c->clean_zn_cnt may become negative for a
+ * while.
+ *
+ * Q: why we cannot increment @c->clean_zn_cnt?
+ * A: because we do not have the @c->tnc_mutex locked, and the
+ * following code would be racy and buggy:
+ *
+ * if (!ubifs_zn_obsolete(znode)) {
+ * atomic_long_inc(&c->clean_zn_cnt);
+ * atomic_long_inc(&ubifs_clean_zn_cnt);
+ * }
+ *
+ * Thus, we just delay the @c->clean_zn_cnt update until we
+ * have the mutex locked.
+ */
+
/* Do not access znode from this point on */
/* Update buffer positions */
--
1.7.2.3
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [PATCH 12/30] UBIFS: amend debugging name check function prototype
2011-06-09 9:04 [PATCH 00/30] UBIFS: latest patches Artem Bityutskiy
` (10 preceding siblings ...)
2011-06-09 9:04 ` [PATCH 11/30] UBIFS: add few commentaries about TNC Artem Bityutskiy
@ 2011-06-09 9:04 ` Artem Bityutskiy
2011-06-09 9:04 ` [PATCH 13/30] UBIFS: amend debugging inode size " Artem Bityutskiy
` (17 subsequent siblings)
29 siblings, 0 replies; 31+ messages in thread
From: Artem Bityutskiy @ 2011-06-09 9:04 UTC (permalink / raw)
To: linux-mtd
From: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
Add 'struct ubifs_info *c' parameter to the 'dbg_check_name()' debugging
function - it will be needed in one of the following commits where we switch to
debugfs. So this is just a preparation.
Mark parameters as 'const' while on it.
Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
---
fs/ubifs/dir.c | 8 +++++---
1 files changed, 5 insertions(+), 3 deletions(-)
diff --git a/fs/ubifs/dir.c b/fs/ubifs/dir.c
index c6cbdd0..d1725a9 100644
--- a/fs/ubifs/dir.c
+++ b/fs/ubifs/dir.c
@@ -172,7 +172,9 @@ struct inode *ubifs_new_inode(struct ubifs_info *c, const struct inode *dir,
#ifdef CONFIG_UBIFS_FS_DEBUG
-static int dbg_check_name(struct ubifs_dent_node *dent, struct qstr *nm)
+static int dbg_check_name(const struct ubifs_info *c,
+ const struct ubifs_dent_node *dent,
+ const struct qstr *nm)
{
if (!(ubifs_chk_flags & UBIFS_CHK_GEN))
return 0;
@@ -185,7 +187,7 @@ static int dbg_check_name(struct ubifs_dent_node *dent, struct qstr *nm)
#else
-#define dbg_check_name(dent, nm) 0
+#define dbg_check_name(c, dent, nm) 0
#endif
@@ -219,7 +221,7 @@ static struct dentry *ubifs_lookup(struct inode *dir, struct dentry *dentry,
goto out;
}
- if (dbg_check_name(dent, &dentry->d_name)) {
+ if (dbg_check_name(c, dent, &dentry->d_name)) {
err = -EINVAL;
goto out;
}
--
1.7.2.3
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [PATCH 13/30] UBIFS: amend debugging inode size check function prototype
2011-06-09 9:04 [PATCH 00/30] UBIFS: latest patches Artem Bityutskiy
` (11 preceding siblings ...)
2011-06-09 9:04 ` [PATCH 12/30] UBIFS: amend debugging name check function prototype Artem Bityutskiy
@ 2011-06-09 9:04 ` Artem Bityutskiy
2011-06-09 9:04 ` [PATCH 14/30] UBIFS: introduce helper functions for debugging checks and tests Artem Bityutskiy
` (16 subsequent siblings)
29 siblings, 0 replies; 31+ messages in thread
From: Artem Bityutskiy @ 2011-06-09 9:04 UTC (permalink / raw)
To: linux-mtd
From: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
Add 'const struct ubifs_info *c' parameter to 'dbg_check_synced_i_size()'
function because we'll need it in the next patch when we switch to debugfs.
So this patch is just a preparation.
Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
---
fs/ubifs/debug.c | 3 ++-
fs/ubifs/debug.h | 6 ++++--
fs/ubifs/dir.c | 4 ++--
fs/ubifs/file.c | 2 +-
4 files changed, 9 insertions(+), 6 deletions(-)
diff --git a/fs/ubifs/debug.c b/fs/ubifs/debug.c
index 26d4c61..7adf9fe 100644
--- a/fs/ubifs/debug.c
+++ b/fs/ubifs/debug.c
@@ -1132,6 +1132,7 @@ out:
/**
* dbg_check_synced_i_size - check synchronized inode size.
+ * @c: UBIFS file-system description object
* @inode: inode to check
*
* If inode is clean, synchronized inode size has to be equivalent to current
@@ -1139,7 +1140,7 @@ out:
* has to be locked). Returns %0 if synchronized inode size if correct, and
* %-EINVAL if not.
*/
-int dbg_check_synced_i_size(struct inode *inode)
+int dbg_check_synced_i_size(const struct ubifs_info *c, struct inode *inode)
{
int err = 0;
struct ubifs_inode *ui = ubifs_inode(inode);
diff --git a/fs/ubifs/debug.h b/fs/ubifs/debug.h
index a51c20b..90805bd 100644
--- a/fs/ubifs/debug.h
+++ b/fs/ubifs/debug.h
@@ -247,7 +247,7 @@ int dbg_check_cats(struct ubifs_info *c);
int dbg_check_ltab(struct ubifs_info *c);
int dbg_chk_lpt_free_spc(struct ubifs_info *c);
int dbg_chk_lpt_sz(struct ubifs_info *c, int action, int len);
-int dbg_check_synced_i_size(struct inode *inode);
+int dbg_check_synced_i_size(const struct ubifs_info *c, struct inode *inode);
int dbg_check_dir(struct ubifs_info *c, const struct inode *dir);
int dbg_check_tnc(struct ubifs_info *c, int extra);
int dbg_check_idx_size(struct ubifs_info *c, long long idx_size);
@@ -416,7 +416,9 @@ static inline int dbg_check_ltab(struct ubifs_info *c) { return 0; }
static inline int dbg_chk_lpt_free_spc(struct ubifs_info *c) { return 0; }
static inline int dbg_chk_lpt_sz(struct ubifs_info *c,
int action, int len) { return 0; }
-static inline int dbg_check_synced_i_size(struct inode *inode) { return 0; }
+static inline int
+dbg_check_synced_i_size(const struct ubifs_info *c,
+ struct inode *inode) { return 0; }
static inline int dbg_check_dir(struct ubifs_info *c,
const struct inode *dir) { return 0; }
static inline int dbg_check_tnc(struct ubifs_info *c, int extra) { return 0; }
diff --git a/fs/ubifs/dir.c b/fs/ubifs/dir.c
index d1725a9..98014bf 100644
--- a/fs/ubifs/dir.c
+++ b/fs/ubifs/dir.c
@@ -524,7 +524,7 @@ static int ubifs_link(struct dentry *old_dentry, struct inode *dir,
ubifs_assert(mutex_is_locked(&dir->i_mutex));
ubifs_assert(mutex_is_locked(&inode->i_mutex));
- err = dbg_check_synced_i_size(inode);
+ err = dbg_check_synced_i_size(c, inode);
if (err)
return err;
@@ -579,7 +579,7 @@ static int ubifs_unlink(struct inode *dir, struct dentry *dentry)
inode->i_nlink, dir->i_ino);
ubifs_assert(mutex_is_locked(&dir->i_mutex));
ubifs_assert(mutex_is_locked(&inode->i_mutex));
- err = dbg_check_synced_i_size(inode);
+ err = dbg_check_synced_i_size(c, inode);
if (err)
return err;
diff --git a/fs/ubifs/file.c b/fs/ubifs/file.c
index 5e7fccf..7cf738a 100644
--- a/fs/ubifs/file.c
+++ b/fs/ubifs/file.c
@@ -1263,7 +1263,7 @@ int ubifs_setattr(struct dentry *dentry, struct iattr *attr)
if (err)
return err;
- err = dbg_check_synced_i_size(inode);
+ err = dbg_check_synced_i_size(c, inode);
if (err)
return err;
--
1.7.2.3
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [PATCH 14/30] UBIFS: introduce helper functions for debugging checks and tests
2011-06-09 9:04 [PATCH 00/30] UBIFS: latest patches Artem Bityutskiy
` (12 preceding siblings ...)
2011-06-09 9:04 ` [PATCH 13/30] UBIFS: amend debugging inode size " Artem Bityutskiy
@ 2011-06-09 9:04 ` Artem Bityutskiy
2011-06-09 9:04 ` [PATCH 15/30] UBIFS: lessen amount of debugging check types Artem Bityutskiy
` (15 subsequent siblings)
29 siblings, 0 replies; 31+ messages in thread
From: Artem Bityutskiy @ 2011-06-09 9:04 UTC (permalink / raw)
To: linux-mtd
From: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
This patch introduces helper functions for all debugging checks, so instead of
doing
if (!(ubifs_chk_flags & UBIFS_CHK_GEN))
we now do
if (!dbg_is_chk_gen(c))
This is a preparation to further changes where the flags will go away, and
we'll need to only change the helper functions, but the code which utilizes
them won't be touched.
At the same time this patch removes 'dbg_force_in_the_gaps()',
'dbg_force_in_the_gaps_enabled()', and dbg_failure_mode helpers for
consistency.
Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
---
fs/ubifs/commit.c | 2 +-
fs/ubifs/debug.c | 30 ++++++++--------------
fs/ubifs/debug.h | 66 ++++++++++++++++++++++++++++++++++---------------
fs/ubifs/dir.c | 2 +-
fs/ubifs/log.c | 2 +-
fs/ubifs/lprops.c | 6 ++--
fs/ubifs/lpt.c | 2 +-
fs/ubifs/lpt_commit.c | 10 +++---
fs/ubifs/orphan.c | 2 +-
fs/ubifs/scan.c | 2 +-
fs/ubifs/tnc.c | 2 +-
fs/ubifs/tnc_commit.c | 5 ++-
12 files changed, 75 insertions(+), 56 deletions(-)
diff --git a/fs/ubifs/commit.c b/fs/ubifs/commit.c
index 637e076..63c4e44 100644
--- a/fs/ubifs/commit.c
+++ b/fs/ubifs/commit.c
@@ -576,7 +576,7 @@ int dbg_check_old_index(struct ubifs_info *c, struct ubifs_zbranch *zroot)
struct idx_node *i;
size_t sz;
- if (!(ubifs_chk_flags & UBIFS_CHK_OLD_IDX))
+ if (!dbg_is_chk_old_idx(c))
return 0;
INIT_LIST_HEAD(&list);
diff --git a/fs/ubifs/debug.c b/fs/ubifs/debug.c
index 7adf9fe..79d8924 100644
--- a/fs/ubifs/debug.c
+++ b/fs/ubifs/debug.c
@@ -330,7 +330,7 @@ void dbg_dump_node(const struct ubifs_info *c, const void *node)
union ubifs_key key;
const struct ubifs_ch *ch = node;
- if (dbg_failure_mode)
+ if (dbg_is_tst_rcvry(c))
return;
/* If the magic is incorrect, just hexdump the first bytes */
@@ -886,7 +886,7 @@ void dbg_dump_leb(const struct ubifs_info *c, int lnum)
struct ubifs_scan_node *snod;
void *buf;
- if (dbg_failure_mode)
+ if (dbg_is_tst_rcvry(c))
return;
printk(KERN_DEBUG "(pid %d) start dumping LEB %d\n",
@@ -1145,7 +1145,7 @@ int dbg_check_synced_i_size(const struct ubifs_info *c, struct inode *inode)
int err = 0;
struct ubifs_inode *ui = ubifs_inode(inode);
- if (!(ubifs_chk_flags & UBIFS_CHK_GEN))
+ if (!dbg_is_chk_gen(c))
return 0;
if (!S_ISREG(inode->i_mode))
return 0;
@@ -1186,7 +1186,7 @@ int dbg_check_dir(struct ubifs_info *c, const struct inode *dir)
struct qstr nm = { .name = NULL };
loff_t size = UBIFS_INO_NODE_SZ;
- if (!(ubifs_chk_flags & UBIFS_CHK_GEN))
+ if (!dbg_is_chk_gen(c))
return 0;
if (!S_ISDIR(dir->i_mode))
@@ -1544,7 +1544,7 @@ int dbg_check_tnc(struct ubifs_info *c, int extra)
long clean_cnt = 0, dirty_cnt = 0;
int err, last;
- if (!(ubifs_chk_flags & UBIFS_CHK_TNC))
+ if (!dbg_is_chk_tnc(c))
return 0;
ubifs_assert(mutex_is_locked(&c->tnc_mutex));
@@ -1791,7 +1791,7 @@ int dbg_check_idx_size(struct ubifs_info *c, long long idx_size)
int err;
long long calc = 0;
- if (!(ubifs_chk_flags & UBIFS_CHK_IDX_SZ))
+ if (!dbg_is_chk_idx_sz(c))
return 0;
err = dbg_walk_index(c, NULL, add_size, &calc);
@@ -2367,7 +2367,7 @@ int dbg_check_filesystem(struct ubifs_info *c)
int err;
struct fsck_data fsckd;
- if (!(ubifs_chk_flags & UBIFS_CHK_FS))
+ if (!dbg_is_chk_fs(c))
return 0;
fsckd.inodes = RB_ROOT;
@@ -2402,7 +2402,7 @@ int dbg_check_data_nodes_order(struct ubifs_info *c, struct list_head *head)
struct list_head *cur;
struct ubifs_scan_node *sa, *sb;
- if (!(ubifs_chk_flags & UBIFS_CHK_GEN))
+ if (!dbg_is_chk_gen(c))
return 0;
for (cur = head->next; cur->next != head; cur = cur->next) {
@@ -2469,7 +2469,7 @@ int dbg_check_nondata_nodes_order(struct ubifs_info *c, struct list_head *head)
struct list_head *cur;
struct ubifs_scan_node *sa, *sb;
- if (!(ubifs_chk_flags & UBIFS_CHK_GEN))
+ if (!dbg_is_chk_gen(c))
return 0;
for (cur = head->next; cur->next != head; cur = cur->next) {
@@ -2546,14 +2546,6 @@ error_dump:
return 0;
}
-int dbg_force_in_the_gaps(void)
-{
- if (!(ubifs_chk_flags & UBIFS_CHK_GEN))
- return 0;
-
- return !(random32() & 7);
-}
-
/* Failure mode for recovery testing */
#define chance(n, d) (simple_rand() <= (n) * 32768LL / (d))
@@ -2624,7 +2616,7 @@ static int in_failure_mode(struct ubi_volume_desc *desc)
{
struct ubifs_info *c = dbg_find_info(desc);
- if (c && dbg_failure_mode)
+ if (c && dbg_is_tst_rcvry(c))
return c->dbg->failure_mode;
return 0;
}
@@ -2634,7 +2626,7 @@ static int do_fail(struct ubi_volume_desc *desc, int lnum, int write)
struct ubifs_info *c = dbg_find_info(desc);
struct ubifs_debug_info *d;
- if (!c || !dbg_failure_mode)
+ if (!c || !dbg_is_tst_rcvry(c))
return 0;
d = c->dbg;
if (d->failure_mode)
diff --git a/fs/ubifs/debug.h b/fs/ubifs/debug.h
index 90805bd..c3d1ffd 100644
--- a/fs/ubifs/debug.h
+++ b/fs/ubifs/debug.h
@@ -31,8 +31,6 @@ typedef int (*dbg_znode_callback)(struct ubifs_info *c,
#ifdef CONFIG_UBIFS_FS_DEBUG
-#include <linux/random.h>
-
/*
* The UBIFS debugfs directory name pattern and maximum name length (3 for "ubi"
* + 1 for "_" and plus 2x2 for 2 UBI numbers and 1 for the trailing zero byte.
@@ -169,6 +167,8 @@ const char *dbg_key_str1(const struct ubifs_info *c,
/* Additional recovery messages */
#define dbg_rcvry(fmt, ...) ubifs_dbg_msg("rcvry", fmt, ##__VA_ARGS__)
+extern spinlock_t dbg_lock;
+
/*
* Debugging check flags.
*
@@ -199,12 +199,43 @@ enum {
UBIFS_TST_RCVRY = 0x4,
};
-extern spinlock_t dbg_lock;
-
extern unsigned int ubifs_msg_flags;
extern unsigned int ubifs_chk_flags;
extern unsigned int ubifs_tst_flags;
+static inline int dbg_is_chk_gen(const struct ubifs_info *c)
+{
+ return !!(ubifs_chk_flags & UBIFS_CHK_GEN);
+}
+static inline int dbg_is_chk_tnc(const struct ubifs_info *c)
+{
+ return !!(ubifs_chk_flags & UBIFS_CHK_TNC);
+}
+static inline int dbg_is_chk_idx_sz(const struct ubifs_info *c)
+{
+ return !!(ubifs_chk_flags & UBIFS_CHK_IDX_SZ);
+}
+static inline int dbg_is_chk_orph(const struct ubifs_info *c)
+{
+ return !!(ubifs_chk_flags & UBIFS_CHK_ORPH);
+}
+static inline int dbg_is_chk_old_idx(const struct ubifs_info *c)
+{
+ return !!(ubifs_chk_flags & UBIFS_CHK_OLD_IDX);
+}
+static inline int dbg_is_chk_lprops(const struct ubifs_info *c)
+{
+ return !!(ubifs_chk_flags & UBIFS_CHK_LPROPS);
+}
+static inline int dbg_is_chk_fs(const struct ubifs_info *c)
+{
+ return !!(ubifs_chk_flags & UBIFS_CHK_FS);
+}
+static inline int dbg_is_tst_rcvry(const struct ubifs_info *c)
+{
+ return !!(ubifs_tst_flags & UBIFS_TST_RCVRY);
+}
+
int ubifs_debugging_init(struct ubifs_info *c);
void ubifs_debugging_exit(struct ubifs_info *c);
@@ -261,16 +292,6 @@ int dbg_check_inode_size(struct ubifs_info *c, const struct inode *inode,
int dbg_check_data_nodes_order(struct ubifs_info *c, struct list_head *head);
int dbg_check_nondata_nodes_order(struct ubifs_info *c, struct list_head *head);
-/* Force the use of in-the-gaps method for testing */
-static inline int dbg_force_in_the_gaps_enabled(void)
-{
- return ubifs_chk_flags & UBIFS_CHK_GEN;
-}
-int dbg_force_in_the_gaps(void);
-
-/* Failure mode for recovery testing */
-#define dbg_failure_mode (ubifs_tst_flags & UBIFS_TST_RCVRY)
-
#ifndef UBIFS_DBG_PRESERVE_UBI
#define ubi_leb_read dbg_leb_read
#define ubi_leb_write dbg_leb_write
@@ -330,6 +351,9 @@ void dbg_debugfs_exit_fs(struct ubifs_info *c);
ubifs_err(fmt, ##__VA_ARGS__); \
} while (0)
+#define DBGKEY(key) ((char *)(key))
+#define DBGKEY1(key) ((char *)(key))
+
#define ubifs_dbg_msg(fmt, ...) do { \
if (0) \
pr_debug(fmt "\n", ##__VA_ARGS__); \
@@ -353,9 +377,6 @@ void dbg_debugfs_exit_fs(struct ubifs_info *c);
#define dbg_scan(fmt, ...) ubifs_dbg_msg(fmt, ##__VA_ARGS__)
#define dbg_rcvry(fmt, ...) ubifs_dbg_msg(fmt, ##__VA_ARGS__)
-#define DBGKEY(key) ((char *)(key))
-#define DBGKEY1(key) ((char *)(key))
-
static inline int ubifs_debugging_init(struct ubifs_info *c) { return 0; }
static inline void ubifs_debugging_exit(struct ubifs_info *c) { return; }
static inline const char *dbg_ntype(int type) { return ""; }
@@ -440,9 +461,14 @@ static inline int
dbg_check_nondata_nodes_order(struct ubifs_info *c,
struct list_head *head) { return 0; }
-static inline int dbg_force_in_the_gaps(void) { return 0; }
-#define dbg_force_in_the_gaps_enabled() 0
-#define dbg_failure_mode 0
+static inline int dbg_is_chk_gen(const struct ubifs_info *c) { return 0; }
+static inline int dbg_is_chk_tnc(const struct ubifs_info *c) { return 0; }
+static inline int dbg_is_chk_idx_sz(const struct ubifs_info *c) { return 0; }
+static inline int dbg_is_chk_orph(const struct ubifs_info *c) { return 0; }
+static inline int dbg_is_chk_old_idx(const struct ubifs_info *c) { return 0; }
+static inline int dbg_is_chk_lprops(const struct ubifs_info *c) { return 0; }
+static inline int dbg_is_chk_fs(const struct ubifs_info *c) { return 0; }
+static inline int dbg_is_tst_rcvry(const struct ubifs_info *c) { return 0; }
static inline int dbg_debugfs_init(void) { return 0; }
static inline void dbg_debugfs_exit(void) { return; }
diff --git a/fs/ubifs/dir.c b/fs/ubifs/dir.c
index 98014bf..6834920 100644
--- a/fs/ubifs/dir.c
+++ b/fs/ubifs/dir.c
@@ -176,7 +176,7 @@ static int dbg_check_name(const struct ubifs_info *c,
const struct ubifs_dent_node *dent,
const struct qstr *nm)
{
- if (!(ubifs_chk_flags & UBIFS_CHK_GEN))
+ if (!dbg_is_chk_gen(c))
return 0;
if (le16_to_cpu(dent->nlen) != nm->len)
return -EINVAL;
diff --git a/fs/ubifs/log.c b/fs/ubifs/log.c
index affea94..fabfb53 100644
--- a/fs/ubifs/log.c
+++ b/fs/ubifs/log.c
@@ -752,7 +752,7 @@ static int dbg_check_bud_bytes(struct ubifs_info *c)
struct ubifs_bud *bud;
long long bud_bytes = 0;
- if (!(ubifs_chk_flags & UBIFS_CHK_GEN))
+ if (!dbg_is_chk_gen(c))
return 0;
spin_lock(&c->buds_lock);
diff --git a/fs/ubifs/lprops.c b/fs/ubifs/lprops.c
index 98b8e73..f8a181e 100644
--- a/fs/ubifs/lprops.c
+++ b/fs/ubifs/lprops.c
@@ -860,7 +860,7 @@ int dbg_check_cats(struct ubifs_info *c)
struct list_head *pos;
int i, cat;
- if (!(ubifs_chk_flags & (UBIFS_CHK_GEN | UBIFS_CHK_LPROPS)))
+ if (!dbg_is_chk_gen(c) && !dbg_is_chk_lprops(c))
return 0;
list_for_each_entry(lprops, &c->empty_list, list) {
@@ -958,7 +958,7 @@ void dbg_check_heap(struct ubifs_info *c, struct ubifs_lpt_heap *heap, int cat,
{
int i = 0, j, err = 0;
- if (!(ubifs_chk_flags & (UBIFS_CHK_GEN | UBIFS_CHK_LPROPS)))
+ if (!dbg_is_chk_gen(c) && !dbg_is_chk_lprops(c))
return;
for (i = 0; i < heap->cnt; i++) {
@@ -1262,7 +1262,7 @@ int dbg_check_lprops(struct ubifs_info *c)
int i, err;
struct ubifs_lp_stats lst;
- if (!(ubifs_chk_flags & UBIFS_CHK_LPROPS))
+ if (!dbg_is_chk_lprops(c))
return 0;
/*
diff --git a/fs/ubifs/lpt.c b/fs/ubifs/lpt.c
index 04713cd..ab91ca6 100644
--- a/fs/ubifs/lpt.c
+++ b/fs/ubifs/lpt.c
@@ -2226,7 +2226,7 @@ int dbg_check_lpt_nodes(struct ubifs_info *c, struct ubifs_cnode *cnode,
struct ubifs_cnode *cn;
int num, iip = 0, err;
- if (!(ubifs_chk_flags & UBIFS_CHK_LPROPS))
+ if (!dbg_is_chk_lprops(c))
return 0;
while (cnode) {
diff --git a/fs/ubifs/lpt_commit.c b/fs/ubifs/lpt_commit.c
index 254e8d3..f8e286b 100644
--- a/fs/ubifs/lpt_commit.c
+++ b/fs/ubifs/lpt_commit.c
@@ -1640,7 +1640,7 @@ static int dbg_check_ltab_lnum(struct ubifs_info *c, int lnum)
int ret;
void *buf, *p;
- if (!(ubifs_chk_flags & UBIFS_CHK_LPROPS))
+ if (!dbg_is_chk_lprops(c))
return 0;
buf = p = __vmalloc(c->leb_size, GFP_NOFS, PAGE_KERNEL);
@@ -1711,7 +1711,7 @@ int dbg_check_ltab(struct ubifs_info *c)
{
int lnum, err, i, cnt;
- if (!(ubifs_chk_flags & UBIFS_CHK_LPROPS))
+ if (!dbg_is_chk_lprops(c))
return 0;
/* Bring the entire tree into memory */
@@ -1754,7 +1754,7 @@ int dbg_chk_lpt_free_spc(struct ubifs_info *c)
long long free = 0;
int i;
- if (!(ubifs_chk_flags & UBIFS_CHK_LPROPS))
+ if (!dbg_is_chk_lprops(c))
return 0;
for (i = 0; i < c->lpt_lebs; i++) {
@@ -1796,7 +1796,7 @@ int dbg_chk_lpt_sz(struct ubifs_info *c, int action, int len)
long long chk_lpt_sz, lpt_sz;
int err = 0;
- if (!(ubifs_chk_flags & UBIFS_CHK_LPROPS))
+ if (!dbg_is_chk_lprops(c))
return 0;
switch (action) {
@@ -2019,7 +2019,7 @@ static int dbg_populate_lsave(struct ubifs_info *c)
struct ubifs_lpt_heap *heap;
int i;
- if (!(ubifs_chk_flags & UBIFS_CHK_GEN))
+ if (!dbg_is_chk_gen(c))
return 0;
if (random32() & 3)
return 0;
diff --git a/fs/ubifs/orphan.c b/fs/ubifs/orphan.c
index a5422ff..c542c73 100644
--- a/fs/ubifs/orphan.c
+++ b/fs/ubifs/orphan.c
@@ -929,7 +929,7 @@ static int dbg_check_orphans(struct ubifs_info *c)
struct check_info ci;
int err;
- if (!(ubifs_chk_flags & UBIFS_CHK_ORPH))
+ if (!dbg_is_chk_orph(c))
return 0;
ci.last_ino = 0;
diff --git a/fs/ubifs/scan.c b/fs/ubifs/scan.c
index 36216b4..c7df916 100644
--- a/fs/ubifs/scan.c
+++ b/fs/ubifs/scan.c
@@ -240,7 +240,7 @@ void ubifs_scanned_corruption(const struct ubifs_info *c, int lnum, int offs,
int len;
ubifs_err("corruption at LEB %d:%d", lnum, offs);
- if (dbg_failure_mode)
+ if (dbg_is_tst_rcvry(c))
return;
len = c->leb_size - offs;
if (len > 8192)
diff --git a/fs/ubifs/tnc.c b/fs/ubifs/tnc.c
index b32a537..526b63c 100644
--- a/fs/ubifs/tnc.c
+++ b/fs/ubifs/tnc.c
@@ -3300,7 +3300,7 @@ int dbg_check_inode_size(struct ubifs_info *c, const struct inode *inode,
if (!S_ISREG(inode->i_mode))
return 0;
- if (!(ubifs_chk_flags & UBIFS_CHK_GEN))
+ if (!dbg_is_chk_gen(c))
return 0;
block = (size + UBIFS_BLOCK_SIZE - 1) >> UBIFS_BLOCK_SHIFT;
diff --git a/fs/ubifs/tnc_commit.c b/fs/ubifs/tnc_commit.c
index d6fab1a..8959c72 100644
--- a/fs/ubifs/tnc_commit.c
+++ b/fs/ubifs/tnc_commit.c
@@ -23,6 +23,7 @@
/* This file implements TNC functions for committing */
#include "ubifs.h"
+#include <linux/random.h>
/**
* make_idx_node - make an index node for fill-the-gaps method of TNC commit.
@@ -381,7 +382,7 @@ static int layout_in_gaps(struct ubifs_info *c, int cnt)
c->gap_lebs = NULL;
return err;
}
- if (dbg_force_in_the_gaps_enabled()) {
+ if (!dbg_is_chk_gen(c)) {
/*
* Do not print scary warnings if the debugging
* option which forces in-the-gaps is enabled.
@@ -689,7 +690,7 @@ static int alloc_idx_lebs(struct ubifs_info *c, int cnt)
c->ilebs[c->ileb_cnt++] = lnum;
dbg_cmt("LEB %d", lnum);
}
- if (dbg_force_in_the_gaps())
+ if (dbg_is_chk_gen(c) && !(random32() & 7))
return -ENOSPC;
return 0;
}
--
1.7.2.3
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [PATCH 15/30] UBIFS: lessen amount of debugging check types
2011-06-09 9:04 [PATCH 00/30] UBIFS: latest patches Artem Bityutskiy
` (13 preceding siblings ...)
2011-06-09 9:04 ` [PATCH 14/30] UBIFS: introduce helper functions for debugging checks and tests Artem Bityutskiy
@ 2011-06-09 9:04 ` Artem Bityutskiy
2011-06-09 9:04 ` [PATCH 16/30] UBIFS: switch self-check knobs to debugfs Artem Bityutskiy
` (14 subsequent siblings)
29 siblings, 0 replies; 31+ messages in thread
From: Artem Bityutskiy @ 2011-06-09 9:04 UTC (permalink / raw)
To: linux-mtd
From: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
We have too many different debugging checks - lessen the amount by merging all
index-related checks into one. At the same time, move the "force in-the-gap"
test to the "index checks" class, because it is too heavy for the "general"
class.
This patch merges TNC, Old index, and Index size check and calles this just
"index checks".
Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
---
Documentation/filesystems/ubifs.txt | 4 +---
fs/ubifs/commit.c | 2 +-
fs/ubifs/debug.c | 4 ++--
fs/ubifs/debug.h | 24 +++++-------------------
fs/ubifs/lpt_commit.c | 1 +
fs/ubifs/tnc_commit.c | 6 +++---
6 files changed, 13 insertions(+), 28 deletions(-)
diff --git a/Documentation/filesystems/ubifs.txt b/Documentation/filesystems/ubifs.txt
index 8e4fab6..91ef076 100644
--- a/Documentation/filesystems/ubifs.txt
+++ b/Documentation/filesystems/ubifs.txt
@@ -123,10 +123,8 @@ debug_chks Selects extra checks that UBIFS can do while running:
Check Flag value
General checks 1
- Check Tree Node Cache (TNC) 2
- Check indexing tree size 4
+ Check the index 2
Check orphan area 8
- Check old indexing tree 16
Check LEB properties (lprops) 32
Check leaf nodes and inodes 64
diff --git a/fs/ubifs/commit.c b/fs/ubifs/commit.c
index 63c4e44..fb3b5c8 100644
--- a/fs/ubifs/commit.c
+++ b/fs/ubifs/commit.c
@@ -576,7 +576,7 @@ int dbg_check_old_index(struct ubifs_info *c, struct ubifs_zbranch *zroot)
struct idx_node *i;
size_t sz;
- if (!dbg_is_chk_old_idx(c))
+ if (!dbg_is_chk_index(c))
return 0;
INIT_LIST_HEAD(&list);
diff --git a/fs/ubifs/debug.c b/fs/ubifs/debug.c
index 79d8924..a967d68 100644
--- a/fs/ubifs/debug.c
+++ b/fs/ubifs/debug.c
@@ -1544,7 +1544,7 @@ int dbg_check_tnc(struct ubifs_info *c, int extra)
long clean_cnt = 0, dirty_cnt = 0;
int err, last;
- if (!dbg_is_chk_tnc(c))
+ if (!dbg_is_chk_index(c))
return 0;
ubifs_assert(mutex_is_locked(&c->tnc_mutex));
@@ -1791,7 +1791,7 @@ int dbg_check_idx_size(struct ubifs_info *c, long long idx_size)
int err;
long long calc = 0;
- if (!dbg_is_chk_idx_sz(c))
+ if (!dbg_is_chk_index(c))
return 0;
err = dbg_walk_index(c, NULL, add_size, &calc);
diff --git a/fs/ubifs/debug.h b/fs/ubifs/debug.h
index c3d1ffd..44265a3 100644
--- a/fs/ubifs/debug.h
+++ b/fs/ubifs/debug.h
@@ -173,19 +173,15 @@ extern spinlock_t dbg_lock;
* Debugging check flags.
*
* UBIFS_CHK_GEN: general checks
- * UBIFS_CHK_TNC: check TNC
- * UBIFS_CHK_IDX_SZ: check index size
+ * UBIFS_CHK_INDEX: check the index
* UBIFS_CHK_ORPH: check orphans
- * UBIFS_CHK_OLD_IDX: check the old index
* UBIFS_CHK_LPROPS: check lprops
* UBIFS_CHK_FS: check the file-system
*/
enum {
UBIFS_CHK_GEN = 0x1,
- UBIFS_CHK_TNC = 0x2,
- UBIFS_CHK_IDX_SZ = 0x4,
+ UBIFS_CHK_INDEX = 0x2,
UBIFS_CHK_ORPH = 0x8,
- UBIFS_CHK_OLD_IDX = 0x10,
UBIFS_CHK_LPROPS = 0x20,
UBIFS_CHK_FS = 0x40,
};
@@ -207,22 +203,14 @@ static inline int dbg_is_chk_gen(const struct ubifs_info *c)
{
return !!(ubifs_chk_flags & UBIFS_CHK_GEN);
}
-static inline int dbg_is_chk_tnc(const struct ubifs_info *c)
+static inline int dbg_is_chk_index(const struct ubifs_info *c)
{
- return !!(ubifs_chk_flags & UBIFS_CHK_TNC);
-}
-static inline int dbg_is_chk_idx_sz(const struct ubifs_info *c)
-{
- return !!(ubifs_chk_flags & UBIFS_CHK_IDX_SZ);
+ return !!(ubifs_chk_flags & UBIFS_CHK_INDEX);
}
static inline int dbg_is_chk_orph(const struct ubifs_info *c)
{
return !!(ubifs_chk_flags & UBIFS_CHK_ORPH);
}
-static inline int dbg_is_chk_old_idx(const struct ubifs_info *c)
-{
- return !!(ubifs_chk_flags & UBIFS_CHK_OLD_IDX);
-}
static inline int dbg_is_chk_lprops(const struct ubifs_info *c)
{
return !!(ubifs_chk_flags & UBIFS_CHK_LPROPS);
@@ -462,10 +450,8 @@ dbg_check_nondata_nodes_order(struct ubifs_info *c,
struct list_head *head) { return 0; }
static inline int dbg_is_chk_gen(const struct ubifs_info *c) { return 0; }
-static inline int dbg_is_chk_tnc(const struct ubifs_info *c) { return 0; }
-static inline int dbg_is_chk_idx_sz(const struct ubifs_info *c) { return 0; }
+static inline int dbg_is_chk_index(const struct ubifs_info *c) { return 0; }
static inline int dbg_is_chk_orph(const struct ubifs_info *c) { return 0; }
-static inline int dbg_is_chk_old_idx(const struct ubifs_info *c) { return 0; }
static inline int dbg_is_chk_lprops(const struct ubifs_info *c) { return 0; }
static inline int dbg_is_chk_fs(const struct ubifs_info *c) { return 0; }
static inline int dbg_is_tst_rcvry(const struct ubifs_info *c) { return 0; }
diff --git a/fs/ubifs/lpt_commit.c b/fs/ubifs/lpt_commit.c
index f8e286b..f13addf 100644
--- a/fs/ubifs/lpt_commit.c
+++ b/fs/ubifs/lpt_commit.c
@@ -27,6 +27,7 @@
#include <linux/crc16.h>
#include <linux/slab.h>
+#include <linux/random.h>
#include "ubifs.h"
#ifdef CONFIG_UBIFS_FS_DEBUG
diff --git a/fs/ubifs/tnc_commit.c b/fs/ubifs/tnc_commit.c
index 8959c72..4c15f07 100644
--- a/fs/ubifs/tnc_commit.c
+++ b/fs/ubifs/tnc_commit.c
@@ -22,8 +22,8 @@
/* This file implements TNC functions for committing */
-#include "ubifs.h"
#include <linux/random.h>
+#include "ubifs.h"
/**
* make_idx_node - make an index node for fill-the-gaps method of TNC commit.
@@ -382,7 +382,7 @@ static int layout_in_gaps(struct ubifs_info *c, int cnt)
c->gap_lebs = NULL;
return err;
}
- if (!dbg_is_chk_gen(c)) {
+ if (!dbg_is_chk_index(c)) {
/*
* Do not print scary warnings if the debugging
* option which forces in-the-gaps is enabled.
@@ -690,7 +690,7 @@ static int alloc_idx_lebs(struct ubifs_info *c, int cnt)
c->ilebs[c->ileb_cnt++] = lnum;
dbg_cmt("LEB %d", lnum);
}
- if (dbg_is_chk_gen(c) && !(random32() & 7))
+ if (dbg_is_chk_index(c) && !(random32() & 7))
return -ENOSPC;
return 0;
}
--
1.7.2.3
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [PATCH 16/30] UBIFS: switch self-check knobs to debugfs
2011-06-09 9:04 [PATCH 00/30] UBIFS: latest patches Artem Bityutskiy
` (14 preceding siblings ...)
2011-06-09 9:04 ` [PATCH 15/30] UBIFS: lessen amount of debugging check types Artem Bityutskiy
@ 2011-06-09 9:04 ` Artem Bityutskiy
2011-06-09 9:04 ` [PATCH 17/30] UBIFS: be more informative in failure mode Artem Bityutskiy
` (13 subsequent siblings)
29 siblings, 0 replies; 31+ messages in thread
From: Artem Bityutskiy @ 2011-06-09 9:04 UTC (permalink / raw)
To: linux-mtd
From: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
UBIFS has many built-in self-check functions which can be enabled using the
debug_chks module parameter or the corresponding sysfs file
(/sys/module/ubifs/parameters/debug_chks). However, this is not flexible enough
because it is not per-filesystem. This patch moves this to debugfs interfaces.
We already have debugfs support, so this patch just adds more debugfs files.
While looking at debugfs support I've noticed that it is racy WRT file-system
unmount, and added a TODO entry for that. This problem has been there for long
time and it is quite standard debugfs PITA. The plan is to fix this later.
This patch is simple, but it is large because it changes many places where we
check if a particular type of checks is enabled or disabled.
Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
---
Documentation/filesystems/ubifs.txt | 26 -------
fs/ubifs/debug.c | 140 ++++++++++++++++++++++++++++++----
fs/ubifs/debug.h | 72 +++++++++---------
3 files changed, 159 insertions(+), 79 deletions(-)
diff --git a/Documentation/filesystems/ubifs.txt b/Documentation/filesystems/ubifs.txt
index 91ef076..a0a61d2 100644
--- a/Documentation/filesystems/ubifs.txt
+++ b/Documentation/filesystems/ubifs.txt
@@ -111,32 +111,6 @@ The following is an example of the kernel boot arguments to attach mtd0
to UBI and mount volume "rootfs":
ubi.mtd=0 root=ubi0:rootfs rootfstype=ubifs
-
-Module Parameters for Debugging
-===============================
-
-When UBIFS has been compiled with debugging enabled, there are 2 module
-parameters that are available to control aspects of testing and debugging.
-
-debug_chks Selects extra checks that UBIFS can do while running:
-
- Check Flag value
-
- General checks 1
- Check the index 2
- Check orphan area 8
- Check LEB properties (lprops) 32
- Check leaf nodes and inodes 64
-
-debug_tsts Selects a mode of testing, as follows:
-
- Test mode Flag value
-
- Failure mode for recovery testing 4
-
-For example, set debug_chks to 3 to enable general and TNC checks.
-
-
References
==========
diff --git a/fs/ubifs/debug.c b/fs/ubifs/debug.c
index a967d68..fdfa5de 100644
--- a/fs/ubifs/debug.c
+++ b/fs/ubifs/debug.c
@@ -31,9 +31,9 @@
#include "ubifs.h"
#include <linux/module.h>
-#include <linux/moduleparam.h>
#include <linux/debugfs.h>
#include <linux/math64.h>
+#include <linux/uaccess.h>
#ifdef CONFIG_UBIFS_FS_DEBUG
@@ -42,15 +42,6 @@ DEFINE_SPINLOCK(dbg_lock);
static char dbg_key_buf0[128];
static char dbg_key_buf1[128];
-unsigned int ubifs_chk_flags;
-unsigned int ubifs_tst_flags;
-
-module_param_named(debug_chks, ubifs_chk_flags, uint, S_IRUGO | S_IWUSR);
-module_param_named(debug_tsts, ubifs_tst_flags, uint, S_IRUGO | S_IWUSR);
-
-MODULE_PARM_DESC(debug_chks, "Debug check flags");
-MODULE_PARM_DESC(debug_tsts, "Debug special test flags");
-
static const char *get_key_fmt(int fmt)
{
switch (fmt) {
@@ -2886,21 +2877,93 @@ static int open_debugfs_file(struct inode *inode, struct file *file)
return nonseekable_open(inode, file);
}
-static ssize_t write_debugfs_file(struct file *file, const char __user *buf,
- size_t count, loff_t *ppos)
+static ssize_t dfs_file_read(struct file *file, char __user *u, size_t count,
+ loff_t *ppos)
+{
+ struct dentry *dent = file->f_path.dentry;
+ struct ubifs_info *c = file->private_data;
+ struct ubifs_debug_info *d = c->dbg;
+ char buf[3];
+ int val;
+
+ if (dent == d->dfs_chk_gen)
+ val = d->chk_gen;
+ else if (dent == d->dfs_chk_index)
+ val = d->chk_index;
+ else if (dent == d->dfs_chk_orph)
+ val = d->chk_orph;
+ else if (dent == d->dfs_chk_lprops)
+ val = d->chk_lprops;
+ else if (dent == d->dfs_chk_fs)
+ val = d->chk_fs;
+ else if (dent == d->dfs_tst_rcvry)
+ val = d->tst_rcvry;
+ else
+ return -EINVAL;
+
+ if (val)
+ buf[0] = '1';
+ else
+ buf[0] = '0';
+ buf[1] = '\n';
+ buf[2] = 0x00;
+
+ return simple_read_from_buffer(u, count, ppos, buf, 2);
+}
+
+static ssize_t dfs_file_write(struct file *file, const char __user *u,
+ size_t count, loff_t *ppos)
{
struct ubifs_info *c = file->private_data;
struct ubifs_debug_info *d = c->dbg;
+ struct dentry *dent = file->f_path.dentry;
+ size_t buf_size;
+ char buf[8];
+ int val;
- if (file->f_path.dentry == d->dfs_dump_lprops)
+ /*
+ * FIXME: this is racy - the file-system might have already been
+ * unmounted and we'd oops in this case.
+ */
+ if (file->f_path.dentry == d->dfs_dump_lprops) {
dbg_dump_lprops(c);
- else if (file->f_path.dentry == d->dfs_dump_budg)
+ return count;
+ }
+ if (file->f_path.dentry == d->dfs_dump_budg) {
dbg_dump_budg(c, &c->bi);
- else if (file->f_path.dentry == d->dfs_dump_tnc) {
+ return count;
+ }
+ if (file->f_path.dentry == d->dfs_dump_tnc) {
mutex_lock(&c->tnc_mutex);
dbg_dump_tnc(c);
mutex_unlock(&c->tnc_mutex);
- } else
+ return count;
+ }
+
+ buf_size = min_t(size_t, count, (sizeof(buf) - 1));
+ if (copy_from_user(buf, u, buf_size))
+ return -EFAULT;
+
+ if (buf[0] == '1')
+ val = 1;
+ else if (buf[0] == '0')
+ val = 0;
+ else
+ return -EINVAL;
+
+ if (dent == d->dfs_chk_gen)
+ d->chk_gen = val;
+ else if (dent == d->dfs_chk_index)
+ d->chk_index = val;
+ else if (dent == d->dfs_chk_orph)
+ d->chk_orph = val;
+ else if (dent == d->dfs_chk_lprops)
+ d->chk_lprops = val;
+ else if (dent == d->dfs_chk_fs)
+ d->chk_fs = val;
+ else if (dent == d->dfs_tst_rcvry)
+ d->tst_rcvry = val;
+ else
return -EINVAL;
return count;
@@ -2908,7 +2971,8 @@ static ssize_t write_debugfs_file(struct file *file, const char __user *buf,
static const struct file_operations dfs_fops = {
.open = open_debugfs_file,
- .write = write_debugfs_file,
+ .read = dfs_file_read,
+ .write = dfs_file_write,
.owner = THIS_MODULE,
.llseek = no_llseek,
};
@@ -2965,6 +3029,48 @@ int dbg_debugfs_init_fs(struct ubifs_info *c)
goto out_remove;
d->dfs_dump_tnc = dent;
+ fname = "chk_general";
+ dent = debugfs_create_file(fname, S_IRUSR | S_IWUSR, d->dfs_dir, c,
+ &dfs_fops);
+ if (IS_ERR_OR_NULL(dent))
+ goto out_remove;
+ d->dfs_chk_gen = dent;
+
+ fname = "chk_index";
+ dent = debugfs_create_file(fname, S_IRUSR | S_IWUSR, d->dfs_dir, c,
+ &dfs_fops);
+ if (IS_ERR_OR_NULL(dent))
+ goto out_remove;
+ d->dfs_chk_index = dent;
+
+ fname = "chk_orphans";
+ dent = debugfs_create_file(fname, S_IRUSR | S_IWUSR, d->dfs_dir, c,
+ &dfs_fops);
+ if (IS_ERR_OR_NULL(dent))
+ goto out_remove;
+ d->dfs_chk_orph = dent;
+
+ fname = "chk_lprops";
+ dent = debugfs_create_file(fname, S_IRUSR | S_IWUSR, d->dfs_dir, c,
+ &dfs_fops);
+ if (IS_ERR_OR_NULL(dent))
+ goto out_remove;
+ d->dfs_chk_lprops = dent;
+
+ fname = "chk_fs";
+ dent = debugfs_create_file(fname, S_IRUSR | S_IWUSR, d->dfs_dir, c,
+ &dfs_fops);
+ if (IS_ERR_OR_NULL(dent))
+ goto out_remove;
+ d->dfs_chk_fs = dent;
+
+ fname = "tst_recovery";
+ dent = debugfs_create_file(fname, S_IRUSR | S_IWUSR, d->dfs_dir, c,
+ &dfs_fops);
+ if (IS_ERR_OR_NULL(dent))
+ goto out_remove;
+ d->dfs_tst_rcvry = dent;
+
return 0;
out_remove:
diff --git a/fs/ubifs/debug.h b/fs/ubifs/debug.h
index 44265a3..8c3bdd3 100644
--- a/fs/ubifs/debug.h
+++ b/fs/ubifs/debug.h
@@ -43,11 +43,13 @@ typedef int (*dbg_znode_callback)(struct ubifs_info *c,
* @old_zroot: old index root - used by 'dbg_check_old_index()'
* @old_zroot_level: old index root level - used by 'dbg_check_old_index()'
* @old_zroot_sqnum: old index root sqnum - used by 'dbg_check_old_index()'
+ *
* @failure_mode: failure mode for recovery testing
* @fail_delay: 0=>don't delay, 1=>delay a time, 2=>delay a number of calls
* @fail_timeout: time in jiffies when delay of failure mode expires
* @fail_cnt: current number of calls to failure mode I/O functions
* @fail_cnt_max: number of calls by which to delay failure mode
+ *
* @chk_lpt_sz: used by LPT tree size checker
* @chk_lpt_sz2: used by LPT tree size checker
* @chk_lpt_wastage: used by LPT tree size checker
@@ -61,21 +63,36 @@ typedef int (*dbg_znode_callback)(struct ubifs_info *c,
* @saved_free: saved amount of free space
* @saved_idx_gc_cnt: saved value of @c->idx_gc_cnt
*
+ * @chk_gen: if general extra checks are enabled
+ * @chk_index: if index xtra checks are enabled
+ * @chk_orph: if orphans extra checks are enabled
+ * @chk_lprops: if lprops extra checks are enabled
+ * @chk_fs: if UBIFS contents extra checks are enabled
+ * @tst_rcvry: if UBIFS recovery testing mode enabled
+ *
* @dfs_dir_name: name of debugfs directory containing this file-system's files
* @dfs_dir: direntry object of the file-system debugfs directory
* @dfs_dump_lprops: "dump lprops" debugfs knob
* @dfs_dump_budg: "dump budgeting information" debugfs knob
* @dfs_dump_tnc: "dump TNC" debugfs knob
+ * @dfs_chk_gen: debugfs knob to enable UBIFS general extra checks
+ * @dfs_chk_index: debugfs knob to enable UBIFS index extra checks
+ * @dfs_chk_orph: debugfs knob to enable UBIFS orphans extra checks
+ * @dfs_chk_lprops: debugfs knob to enable UBIFS LEP properties extra checks
+ * @dfs_chk_fs: debugfs knob to enable UBIFS contents extra checks
+ * @dfs_tst_rcvry: debugfs knob to enable UBIFS recovery testing
*/
struct ubifs_debug_info {
struct ubifs_zbranch old_zroot;
int old_zroot_level;
unsigned long long old_zroot_sqnum;
+
int failure_mode;
int fail_delay;
unsigned long fail_timeout;
unsigned int fail_cnt;
unsigned int fail_cnt_max;
+
long long chk_lpt_sz;
long long chk_lpt_sz2;
long long chk_lpt_wastage;
@@ -89,11 +106,24 @@ struct ubifs_debug_info {
long long saved_free;
int saved_idx_gc_cnt;
+ unsigned int chk_gen:1;
+ unsigned int chk_index:1;
+ unsigned int chk_orph:1;
+ unsigned int chk_lprops:1;
+ unsigned int chk_fs:1;
+ unsigned int tst_rcvry:1;
+
char dfs_dir_name[UBIFS_DFS_DIR_LEN + 1];
struct dentry *dfs_dir;
struct dentry *dfs_dump_lprops;
struct dentry *dfs_dump_budg;
struct dentry *dfs_dump_tnc;
+ struct dentry *dfs_chk_gen;
+ struct dentry *dfs_chk_index;
+ struct dentry *dfs_chk_orph;
+ struct dentry *dfs_chk_lprops;
+ struct dentry *dfs_chk_fs;
+ struct dentry *dfs_tst_rcvry;
};
#define ubifs_assert(expr) do { \
@@ -169,59 +199,29 @@ const char *dbg_key_str1(const struct ubifs_info *c,
extern spinlock_t dbg_lock;
-/*
- * Debugging check flags.
- *
- * UBIFS_CHK_GEN: general checks
- * UBIFS_CHK_INDEX: check the index
- * UBIFS_CHK_ORPH: check orphans
- * UBIFS_CHK_LPROPS: check lprops
- * UBIFS_CHK_FS: check the file-system
- */
-enum {
- UBIFS_CHK_GEN = 0x1,
- UBIFS_CHK_INDEX = 0x2,
- UBIFS_CHK_ORPH = 0x8,
- UBIFS_CHK_LPROPS = 0x20,
- UBIFS_CHK_FS = 0x40,
-};
-
-/*
- * Special testing flags.
- *
- * UBIFS_TST_RCVRY: failure mode for recovery testing
- */
-enum {
- UBIFS_TST_RCVRY = 0x4,
-};
-
-extern unsigned int ubifs_msg_flags;
-extern unsigned int ubifs_chk_flags;
-extern unsigned int ubifs_tst_flags;
-
static inline int dbg_is_chk_gen(const struct ubifs_info *c)
{
- return !!(ubifs_chk_flags & UBIFS_CHK_GEN);
+ return c->dbg->chk_gen;
}
static inline int dbg_is_chk_index(const struct ubifs_info *c)
{
- return !!(ubifs_chk_flags & UBIFS_CHK_INDEX);
+ return c->dbg->chk_index;
}
static inline int dbg_is_chk_orph(const struct ubifs_info *c)
{
- return !!(ubifs_chk_flags & UBIFS_CHK_ORPH);
+ return c->dbg->chk_orph;
}
static inline int dbg_is_chk_lprops(const struct ubifs_info *c)
{
- return !!(ubifs_chk_flags & UBIFS_CHK_LPROPS);
+ return c->dbg->chk_lprops;
}
static inline int dbg_is_chk_fs(const struct ubifs_info *c)
{
- return !!(ubifs_chk_flags & UBIFS_CHK_FS);
+ return c->dbg->chk_fs;
}
static inline int dbg_is_tst_rcvry(const struct ubifs_info *c)
{
- return !!(ubifs_tst_flags & UBIFS_TST_RCVRY);
+ return c->dbg->tst_rcvry;
}
int ubifs_debugging_init(struct ubifs_info *c);
--
1.7.2.3
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [PATCH 17/30] UBIFS: be more informative in failure mode
2011-06-09 9:04 [PATCH 00/30] UBIFS: latest patches Artem Bityutskiy
` (15 preceding siblings ...)
2011-06-09 9:04 ` [PATCH 16/30] UBIFS: switch self-check knobs to debugfs Artem Bityutskiy
@ 2011-06-09 9:04 ` Artem Bityutskiy
2011-06-09 9:04 ` [PATCH 18/30] UBIFS: re-arrange debugging code a bit Artem Bityutskiy
` (12 subsequent siblings)
29 siblings, 0 replies; 31+ messages in thread
From: Artem Bityutskiy @ 2011-06-09 9:04 UTC (permalink / raw)
To: linux-mtd
From: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
When we are testing UBIFS recovery, it is better to print in which eraseblock
we are going to fail. Currently UBIFS prints it only if recovery debugging
messages are enabled, but this is not very practical. So change 'dbg_rcvry()'
messages to 'ubifs_warn()' messages.
Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
---
fs/ubifs/debug.c | 26 +++++++++++++-------------
1 files changed, 13 insertions(+), 13 deletions(-)
diff --git a/fs/ubifs/debug.c b/fs/ubifs/debug.c
index fdfa5de..05fae3f 100644
--- a/fs/ubifs/debug.c
+++ b/fs/ubifs/debug.c
@@ -2631,11 +2631,11 @@ static int do_fail(struct ubi_volume_desc *desc, int lnum, int write)
d->fail_delay = 1;
d->fail_timeout = jiffies +
msecs_to_jiffies(delay);
- dbg_rcvry("failing after %ums", delay);
+ ubifs_warn("failing after %ums", delay);
} else {
d->fail_delay = 2;
d->fail_cnt_max = delay;
- dbg_rcvry("failing after %u calls", delay);
+ ubifs_warn("failing after %u calls", delay);
}
}
d->fail_cnt += 1;
@@ -2653,56 +2653,56 @@ static int do_fail(struct ubi_volume_desc *desc, int lnum, int write)
return 0;
} else if (chance(19, 20))
return 0;
- dbg_rcvry("failing in super block LEB %d", lnum);
+ ubifs_warn("failing in super block LEB %d", lnum);
} else if (lnum == UBIFS_MST_LNUM || lnum == UBIFS_MST_LNUM + 1) {
if (chance(19, 20))
return 0;
- dbg_rcvry("failing in master LEB %d", lnum);
+ ubifs_warn("failing in master LEB %d", lnum);
} else if (lnum >= UBIFS_LOG_LNUM && lnum <= c->log_last) {
if (write) {
if (chance(99, 100))
return 0;
} else if (chance(399, 400))
return 0;
- dbg_rcvry("failing in log LEB %d", lnum);
+ ubifs_warn("failing in log LEB %d", lnum);
} else if (lnum >= c->lpt_first && lnum <= c->lpt_last) {
if (write) {
if (chance(7, 8))
return 0;
} else if (chance(19, 20))
return 0;
- dbg_rcvry("failing in LPT LEB %d", lnum);
+ ubifs_warn("failing in LPT LEB %d", lnum);
} else if (lnum >= c->orph_first && lnum <= c->orph_last) {
if (write) {
if (chance(1, 2))
return 0;
} else if (chance(9, 10))
return 0;
- dbg_rcvry("failing in orphan LEB %d", lnum);
+ ubifs_warn("failing in orphan LEB %d", lnum);
} else if (lnum == c->ihead_lnum) {
if (chance(99, 100))
return 0;
- dbg_rcvry("failing in index head LEB %d", lnum);
+ ubifs_warn("failing in index head LEB %d", lnum);
} else if (c->jheads && lnum == c->jheads[GCHD].wbuf.lnum) {
if (chance(9, 10))
return 0;
- dbg_rcvry("failing in GC head LEB %d", lnum);
+ ubifs_warn("failing in GC head LEB %d", lnum);
} else if (write && !RB_EMPTY_ROOT(&c->buds) &&
!ubifs_search_bud(c, lnum)) {
if (chance(19, 20))
return 0;
- dbg_rcvry("failing in non-bud LEB %d", lnum);
+ ubifs_warn("failing in non-bud LEB %d", lnum);
} else if (c->cmt_state == COMMIT_RUNNING_BACKGROUND ||
c->cmt_state == COMMIT_RUNNING_REQUIRED) {
if (chance(999, 1000))
return 0;
- dbg_rcvry("failing in bud LEB %d commit running", lnum);
+ ubifs_warn("failing in bud LEB %d commit running", lnum);
} else {
if (chance(9999, 10000))
return 0;
- dbg_rcvry("failing in bud LEB %d commit not running", lnum);
+ ubifs_warn("failing in bud LEB %d commit not running", lnum);
}
- ubifs_err("*** SETTING FAILURE MODE ON (LEB %d) ***", lnum);
+
d->failure_mode = 1;
dump_stack();
return 1;
--
1.7.2.3
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [PATCH 18/30] UBIFS: re-arrange debugging code a bit
2011-06-09 9:04 [PATCH 00/30] UBIFS: latest patches Artem Bityutskiy
` (16 preceding siblings ...)
2011-06-09 9:04 ` [PATCH 17/30] UBIFS: be more informative in failure mode Artem Bityutskiy
@ 2011-06-09 9:04 ` Artem Bityutskiy
2011-06-09 9:04 ` [PATCH 19/30] UBIFS: introduce debugfs helpers Artem Bityutskiy
` (11 subsequent siblings)
29 siblings, 0 replies; 31+ messages in thread
From: Artem Bityutskiy @ 2011-06-09 9:04 UTC (permalink / raw)
To: linux-mtd
From: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
Move 'dbg_debugfs_init()' and 'dbg_debugfs_exit()' functions which initialize
debugfs for whole UBIFS subsystem below the code which initializes debugfs for
a particular UBIFS instance. And do the same for 'ubifs_debugging_init()' and
'ubifs_debugging_exit()' functions. This layout is a bit better for the next
patches, so this is just a preparation.
Also, rename 'open_debugfs_file()' into 'dfs_file_open()' for consistency.
Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
---
fs/ubifs/debug.c | 118 +++++++++++++++++++++++++++---------------------------
1 files changed, 59 insertions(+), 59 deletions(-)
diff --git a/fs/ubifs/debug.c b/fs/ubifs/debug.c
index 05fae3f..515658c 100644
--- a/fs/ubifs/debug.c
+++ b/fs/ubifs/debug.c
@@ -2808,70 +2808,13 @@ int dbg_leb_map(struct ubi_volume_desc *desc, int lnum, int dtype)
return 0;
}
-/**
- * ubifs_debugging_init - initialize UBIFS debugging.
- * @c: UBIFS file-system description object
- *
- * This function initializes debugging-related data for the file system.
- * Returns zero in case of success and a negative error code in case of
- * failure.
- */
-int ubifs_debugging_init(struct ubifs_info *c)
-{
- c->dbg = kzalloc(sizeof(struct ubifs_debug_info), GFP_KERNEL);
- if (!c->dbg)
- return -ENOMEM;
-
- failure_mode_init(c);
- return 0;
-}
-
-/**
- * ubifs_debugging_exit - free debugging data.
- * @c: UBIFS file-system description object
- */
-void ubifs_debugging_exit(struct ubifs_info *c)
-{
- failure_mode_exit(c);
- kfree(c->dbg);
-}
-
/*
* Root directory for UBIFS stuff in debugfs. Contains sub-directories which
* contain the stuff specific to particular file-system mounts.
*/
static struct dentry *dfs_rootdir;
-/**
- * dbg_debugfs_init - initialize debugfs file-system.
- *
- * UBIFS uses debugfs file-system to expose various debugging knobs to
- * user-space. This function creates "ubifs" directory in the debugfs
- * file-system. Returns zero in case of success and a negative error code in
- * case of failure.
- */
-int dbg_debugfs_init(void)
-{
- dfs_rootdir = debugfs_create_dir("ubifs", NULL);
- if (IS_ERR_OR_NULL(dfs_rootdir)) {
- int err = dfs_rootdir ? PTR_ERR(dfs_rootdir) : -ENODEV;
- ubifs_err("cannot create \"ubifs\" debugfs directory, "
- "error %d\n", err);
- return err;
- }
-
- return 0;
-}
-
-/**
- * dbg_debugfs_exit - remove the "ubifs" directory from debugfs file-system.
- */
-void dbg_debugfs_exit(void)
-{
- debugfs_remove(dfs_rootdir);
-}
-
-static int open_debugfs_file(struct inode *inode, struct file *file)
+static int dfs_file_open(struct inode *inode, struct file *file)
{
file->private_data = inode->i_private;
return nonseekable_open(inode, file);
@@ -2970,7 +2913,7 @@ static ssize_t dfs_file_write(struct file *file, const char __user *u,
}
static const struct file_operations dfs_fops = {
- .open = open_debugfs_file,
+ .open = dfs_file_open,
.read = dfs_file_read,
.write = dfs_file_write,
.owner = THIS_MODULE,
@@ -3091,4 +3034,61 @@ void dbg_debugfs_exit_fs(struct ubifs_info *c)
debugfs_remove_recursive(c->dbg->dfs_dir);
}
+/**
+ * dbg_debugfs_init - initialize debugfs file-system.
+ *
+ * UBIFS uses debugfs file-system to expose various debugging knobs to
+ * user-space. This function creates "ubifs" directory in the debugfs
+ * file-system. Returns zero in case of success and a negative error code in
+ * case of failure.
+ */
+int dbg_debugfs_init(void)
+{
+ dfs_rootdir = debugfs_create_dir("ubifs", NULL);
+ if (IS_ERR_OR_NULL(dfs_rootdir)) {
+ int err = dfs_rootdir ? PTR_ERR(dfs_rootdir) : -ENODEV;
+ ubifs_err("cannot create \"ubifs\" debugfs directory, "
+ "error %d\n", err);
+ return err;
+ }
+
+ return 0;
+}
+
+/**
+ * dbg_debugfs_exit - remove the "ubifs" directory from debugfs file-system.
+ */
+void dbg_debugfs_exit(void)
+{
+ debugfs_remove(dfs_rootdir);
+}
+
+/**
+ * ubifs_debugging_init - initialize UBIFS debugging.
+ * @c: UBIFS file-system description object
+ *
+ * This function initializes debugging-related data for the file system.
+ * Returns zero in case of success and a negative error code in case of
+ * failure.
+ */
+int ubifs_debugging_init(struct ubifs_info *c)
+{
+ c->dbg = kzalloc(sizeof(struct ubifs_debug_info), GFP_KERNEL);
+ if (!c->dbg)
+ return -ENOMEM;
+
+ failure_mode_init(c);
+ return 0;
+}
+
+/**
+ * ubifs_debugging_exit - free debugging data.
+ * @c: UBIFS file-system description object
+ */
+void ubifs_debugging_exit(struct ubifs_info *c)
+{
+ failure_mode_exit(c);
+ kfree(c->dbg);
+}
+
#endif /* CONFIG_UBIFS_FS_DEBUG */
--
1.7.2.3
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [PATCH 19/30] UBIFS: introduce debugfs helpers
2011-06-09 9:04 [PATCH 00/30] UBIFS: latest patches Artem Bityutskiy
` (17 preceding siblings ...)
2011-06-09 9:04 ` [PATCH 18/30] UBIFS: re-arrange debugging code a bit Artem Bityutskiy
@ 2011-06-09 9:04 ` Artem Bityutskiy
2011-06-09 9:05 ` [PATCH 20/30] UBIFS: add global debugfs knobs Artem Bityutskiy
` (10 subsequent siblings)
29 siblings, 0 replies; 31+ messages in thread
From: Artem Bityutskiy @ 2011-06-09 9:04 UTC (permalink / raw)
To: linux-mtd
From: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
Separate out pieces of code from the debugfs file read/write functions and
create separate 'interpret_user_input()'/'provide_user_output()' helpers. These
helpers will be needed in one of the following patches, so this is just a
preparational change.
Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
---
fs/ubifs/debug.c | 76 +++++++++++++++++++++++++++++++++++++++--------------
1 files changed, 56 insertions(+), 20 deletions(-)
diff --git a/fs/ubifs/debug.c b/fs/ubifs/debug.c
index 515658c..91ac72c 100644
--- a/fs/ubifs/debug.c
+++ b/fs/ubifs/debug.c
@@ -2820,13 +2820,39 @@ static int dfs_file_open(struct inode *inode, struct file *file)
return nonseekable_open(inode, file);
}
+/**
+ * provide_user_output - provide output to the user reading a debugfs file.
+ * @val: boolean value for the answer
+ * @u: the buffer to store the answer at
+ * @count: size of the buffer
+ * @ppos: position in the @u output buffer
+ *
+ * This is a simple helper function which stores @val boolean value in the user
+ * buffer when the user reads one of UBIFS debugfs files. Returns amount of
+ * bytes written to @u in case of success and a negative error code in case of
+ * failure.
+ */
+static int provide_user_output(int val, char __user *u, size_t count,
+ loff_t *ppos)
+{
+ char buf[3];
+
+ if (val)
+ buf[0] = '1';
+ else
+ buf[0] = '0';
+ buf[1] = '\n';
+ buf[2] = 0x00;
+
+ return simple_read_from_buffer(u, count, ppos, buf, 2);
+}
+
static ssize_t dfs_file_read(struct file *file, char __user *u, size_t count,
loff_t *ppos)
{
struct dentry *dent = file->f_path.dentry;
struct ubifs_info *c = file->private_data;
struct ubifs_debug_info *d = c->dbg;
- char buf[3];
int val;
if (dent == d->dfs_chk_gen)
@@ -2844,14 +2870,33 @@ static ssize_t dfs_file_read(struct file *file, char __user *u, size_t count,
else
return -EINVAL;
- if (val)
- buf[0] = '1';
- else
- buf[0] = '0';
- buf[1] = '\n';
- buf[2] = 0x00;
+ return provide_user_output(val, u, count, ppos);
+}
- return simple_read_from_buffer(u, count, ppos, buf, 2);
+/**
+ * interpret_user_input - interpret user debugfs file input.
+ * @u: user-provided buffer with the input
+ * @count: buffer size
+ *
+ * This is a helper function which interpret user input to a boolean UBIFS
+ * debugfs file. Returns %0 or %1 in case of success and a negative error code
+ * in case of failure.
+ */
+static int interpret_user_input(const char __user *u, size_t count)
+{
+ size_t buf_size;
+ char buf[8];
+
+ buf_size = min_t(size_t, count, (sizeof(buf) - 1));
+ if (copy_from_user(buf, u, buf_size))
+ return -EFAULT;
+
+ if (buf[0] == '1')
+ return 1;
+ else if (buf[0] == '0')
+ return 0;
+
+ return -EINVAL;
}
static ssize_t dfs_file_write(struct file *file, const char __user *u,
@@ -2860,8 +2905,6 @@ static ssize_t dfs_file_write(struct file *file, const char __user *u,
struct ubifs_info *c = file->private_data;
struct ubifs_debug_info *d = c->dbg;
struct dentry *dent = file->f_path.dentry;
- size_t buf_size;
- char buf[8];
int val;
/*
@@ -2883,16 +2926,9 @@ static ssize_t dfs_file_write(struct file *file, const char __user *u,
return count;
}
- buf_size = min_t(size_t, count, (sizeof(buf) - 1));
- if (copy_from_user(buf, u, buf_size))
- return -EFAULT;
-
- if (buf[0] == '1')
- val = 1;
- else if (buf[0] == '0')
- val = 0;
- else
- return -EINVAL;
+ val = interpret_user_input(u, count);
+ if (val < 0)
+ return val;
if (dent == d->dfs_chk_gen)
d->chk_gen = val;
--
1.7.2.3
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [PATCH 20/30] UBIFS: add global debugfs knobs
2011-06-09 9:04 [PATCH 00/30] UBIFS: latest patches Artem Bityutskiy
` (18 preceding siblings ...)
2011-06-09 9:04 ` [PATCH 19/30] UBIFS: introduce debugfs helpers Artem Bityutskiy
@ 2011-06-09 9:05 ` Artem Bityutskiy
2011-06-09 9:05 ` [PATCH 21/30] UBIFS: remove unused and unneeded debugging function Artem Bityutskiy
` (9 subsequent siblings)
29 siblings, 0 replies; 31+ messages in thread
From: Artem Bityutskiy @ 2011-06-09 9:05 UTC (permalink / raw)
To: linux-mtd
From: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
Now we have per-FS (superblock) debugfs knobs, but they have one drawback - you
have to first mount the FS and only after this you can switch self-checks
on/off. But often we want to have the checks enabled during the mount.
Introduce global debugging knobs for this purpose.
Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
---
fs/ubifs/debug.c | 138 ++++++++++++++++++++++++++++++++++++++++++++++++++----
fs/ubifs/debug.h | 35 +++++++++++---
2 files changed, 157 insertions(+), 16 deletions(-)
diff --git a/fs/ubifs/debug.c b/fs/ubifs/debug.c
index 91ac72c..741f939 100644
--- a/fs/ubifs/debug.c
+++ b/fs/ubifs/debug.c
@@ -3056,7 +3056,7 @@ out_remove:
debugfs_remove_recursive(d->dfs_dir);
out:
err = dent ? PTR_ERR(dent) : -ENODEV;
- ubifs_err("cannot create \"%s\" debugfs filr or directory, error %d\n",
+ ubifs_err("cannot create \"%s\" debugfs file or directory, error %d\n",
fname, err);
return err;
}
@@ -3070,6 +3070,74 @@ void dbg_debugfs_exit_fs(struct ubifs_info *c)
debugfs_remove_recursive(c->dbg->dfs_dir);
}
+struct ubifs_global_debug_info ubifs_dbg;
+
+static struct dentry *dfs_chk_gen;
+static struct dentry *dfs_chk_index;
+static struct dentry *dfs_chk_orph;
+static struct dentry *dfs_chk_lprops;
+static struct dentry *dfs_chk_fs;
+static struct dentry *dfs_tst_rcvry;
+
+static ssize_t dfs_global_file_read(struct file *file, char __user *u,
+ size_t count, loff_t *ppos)
+{
+ struct dentry *dent = file->f_path.dentry;
+ int val;
+
+ if (dent == dfs_chk_gen)
+ val = ubifs_dbg.chk_gen;
+ else if (dent == dfs_chk_index)
+ val = ubifs_dbg.chk_index;
+ else if (dent == dfs_chk_orph)
+ val = ubifs_dbg.chk_orph;
+ else if (dent == dfs_chk_lprops)
+ val = ubifs_dbg.chk_lprops;
+ else if (dent == dfs_chk_fs)
+ val = ubifs_dbg.chk_fs;
+ else if (dent == dfs_tst_rcvry)
+ val = ubifs_dbg.tst_rcvry;
+ else
+ return -EINVAL;
+
+ return provide_user_output(val, u, count, ppos);
+}
+
+static ssize_t dfs_global_file_write(struct file *file, const char __user *u,
+ size_t count, loff_t *ppos)
+{
+ struct dentry *dent = file->f_path.dentry;
+ int val;
+
+ val = interpret_user_input(u, count);
+ if (val < 0)
+ return val;
+
+ if (dent == dfs_chk_gen)
+ ubifs_dbg.chk_gen = val;
+ else if (dent == dfs_chk_index)
+ ubifs_dbg.chk_index = val;
+ else if (dent == dfs_chk_orph)
+ ubifs_dbg.chk_orph = val;
+ else if (dent == dfs_chk_lprops)
+ ubifs_dbg.chk_lprops = val;
+ else if (dent == dfs_chk_fs)
+ ubifs_dbg.chk_fs = val;
+ else if (dent == dfs_tst_rcvry)
+ ubifs_dbg.tst_rcvry = val;
+ else
+ return -EINVAL;
+
+ return count;
+}
+
+static const struct file_operations dfs_global_fops = {
+ .read = dfs_global_file_read,
+ .write = dfs_global_file_write,
+ .owner = THIS_MODULE,
+ .llseek = no_llseek,
+};
+
/**
* dbg_debugfs_init - initialize debugfs file-system.
*
@@ -3080,15 +3148,67 @@ void dbg_debugfs_exit_fs(struct ubifs_info *c)
*/
int dbg_debugfs_init(void)
{
- dfs_rootdir = debugfs_create_dir("ubifs", NULL);
- if (IS_ERR_OR_NULL(dfs_rootdir)) {
- int err = dfs_rootdir ? PTR_ERR(dfs_rootdir) : -ENODEV;
- ubifs_err("cannot create \"ubifs\" debugfs directory, "
- "error %d\n", err);
- return err;
- }
+ int err;
+ const char *fname;
+ struct dentry *dent;
+
+ fname = "ubifs";
+ dent = debugfs_create_dir(fname, NULL);
+ if (IS_ERR_OR_NULL(dent))
+ goto out;
+ dfs_rootdir = dent;
+
+ fname = "chk_general";
+ dent = debugfs_create_file(fname, S_IRUSR | S_IWUSR, dfs_rootdir, NULL,
+ &dfs_global_fops);
+ if (IS_ERR_OR_NULL(dent))
+ goto out_remove;
+ dfs_chk_gen = dent;
+
+ fname = "chk_index";
+ dent = debugfs_create_file(fname, S_IRUSR | S_IWUSR, dfs_rootdir, NULL,
+ &dfs_global_fops);
+ if (IS_ERR_OR_NULL(dent))
+ goto out_remove;
+ dfs_chk_index = dent;
+
+ fname = "chk_orphans";
+ dent = debugfs_create_file(fname, S_IRUSR | S_IWUSR, dfs_rootdir, NULL,
+ &dfs_global_fops);
+ if (IS_ERR_OR_NULL(dent))
+ goto out_remove;
+ dfs_chk_orph = dent;
+
+ fname = "chk_lprops";
+ dent = debugfs_create_file(fname, S_IRUSR | S_IWUSR, dfs_rootdir, NULL,
+ &dfs_global_fops);
+ if (IS_ERR_OR_NULL(dent))
+ goto out_remove;
+ dfs_chk_lprops = dent;
+
+ fname = "chk_fs";
+ dent = debugfs_create_file(fname, S_IRUSR | S_IWUSR, dfs_rootdir, NULL,
+ &dfs_global_fops);
+ if (IS_ERR_OR_NULL(dent))
+ goto out_remove;
+ dfs_chk_fs = dent;
+
+ fname = "tst_recovery";
+ dent = debugfs_create_file(fname, S_IRUSR | S_IWUSR, dfs_rootdir, NULL,
+ &dfs_global_fops);
+ if (IS_ERR_OR_NULL(dent))
+ goto out_remove;
+ dfs_tst_rcvry = dent;
return 0;
+
+out_remove:
+ debugfs_remove_recursive(dfs_rootdir);
+out:
+ err = dent ? PTR_ERR(dent) : -ENODEV;
+ ubifs_err("cannot create \"%s\" debugfs file or directory, error %d\n",
+ fname, err);
+ return err;
}
/**
@@ -3096,7 +3216,7 @@ int dbg_debugfs_init(void)
*/
void dbg_debugfs_exit(void)
{
- debugfs_remove(dfs_rootdir);
+ debugfs_remove_recursive(dfs_rootdir);
}
/**
diff --git a/fs/ubifs/debug.h b/fs/ubifs/debug.h
index 8c3bdd3..43ec5d1 100644
--- a/fs/ubifs/debug.h
+++ b/fs/ubifs/debug.h
@@ -126,6 +126,25 @@ struct ubifs_debug_info {
struct dentry *dfs_tst_rcvry;
};
+/**
+ * ubifs_global_debug_info - global (not per-FS) UBIFS debugging information.
+ *
+ * @chk_gen: if general extra checks are enabled
+ * @chk_index: if index xtra checks are enabled
+ * @chk_orph: if orphans extra checks are enabled
+ * @chk_lprops: if lprops extra checks are enabled
+ * @chk_fs: if UBIFS contents extra checks are enabled
+ * @tst_rcvry: if UBIFS recovery testing mode enabled
+ */
+struct ubifs_global_debug_info {
+ unsigned int chk_gen:1;
+ unsigned int chk_index:1;
+ unsigned int chk_orph:1;
+ unsigned int chk_lprops:1;
+ unsigned int chk_fs:1;
+ unsigned int tst_rcvry:1;
+};
+
#define ubifs_assert(expr) do { \
if (unlikely(!(expr))) { \
printk(KERN_CRIT "UBIFS assert failed in %s at %u (pid %d)\n", \
@@ -162,6 +181,8 @@ const char *dbg_key_str1(const struct ubifs_info *c,
#define DBGKEY(key) dbg_key_str0(c, (key))
#define DBGKEY1(key) dbg_key_str1(c, (key))
+extern spinlock_t dbg_lock;
+
#define ubifs_dbg_msg(type, fmt, ...) do { \
spin_lock(&dbg_lock); \
pr_debug("UBIFS DBG " type ": " fmt "\n", ##__VA_ARGS__); \
@@ -197,31 +218,31 @@ const char *dbg_key_str1(const struct ubifs_info *c,
/* Additional recovery messages */
#define dbg_rcvry(fmt, ...) ubifs_dbg_msg("rcvry", fmt, ##__VA_ARGS__)
-extern spinlock_t dbg_lock;
+extern struct ubifs_global_debug_info ubifs_dbg;
static inline int dbg_is_chk_gen(const struct ubifs_info *c)
{
- return c->dbg->chk_gen;
+ return !!(ubifs_dbg.chk_gen || c->dbg->chk_gen);
}
static inline int dbg_is_chk_index(const struct ubifs_info *c)
{
- return c->dbg->chk_index;
+ return !!(ubifs_dbg.chk_index || c->dbg->chk_index);
}
static inline int dbg_is_chk_orph(const struct ubifs_info *c)
{
- return c->dbg->chk_orph;
+ return !!(ubifs_dbg.chk_orph || c->dbg->chk_orph);
}
static inline int dbg_is_chk_lprops(const struct ubifs_info *c)
{
- return c->dbg->chk_lprops;
+ return !!(ubifs_dbg.chk_lprops || c->dbg->chk_lprops);
}
static inline int dbg_is_chk_fs(const struct ubifs_info *c)
{
- return c->dbg->chk_fs;
+ return !!(ubifs_dbg.chk_fs || c->dbg->chk_fs);
}
static inline int dbg_is_tst_rcvry(const struct ubifs_info *c)
{
- return c->dbg->tst_rcvry;
+ return !!(ubifs_dbg.tst_rcvry || c->dbg->tst_rcvry);
}
int ubifs_debugging_init(struct ubifs_info *c);
--
1.7.2.3
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [PATCH 21/30] UBIFS: remove unused and unneeded debugging function
2011-06-09 9:04 [PATCH 00/30] UBIFS: latest patches Artem Bityutskiy
` (19 preceding siblings ...)
2011-06-09 9:05 ` [PATCH 20/30] UBIFS: add global debugfs knobs Artem Bityutskiy
@ 2011-06-09 9:05 ` Artem Bityutskiy
2011-06-09 9:05 ` [PATCH 22/30] UBIFS: always print stacktrace when switching to R/O mode Artem Bityutskiy
` (8 subsequent siblings)
29 siblings, 0 replies; 31+ messages in thread
From: Artem Bityutskiy @ 2011-06-09 9:05 UTC (permalink / raw)
To: linux-mtd
From: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
This patch contains several minor clean-up and preparational cahnges.
1. Remove 'dbg_read()', 'dbg_write()', 'dbg_change()', and 'dbg_leb_erase()'
functions as they are not used.
2. Remove 'dbg_leb_read()' and 'dbg_is_mapped()' as they are not really needed,
it is fine to let reads go through in failure mode.
3. Rename 'offset' argument to 'offs' to be consistent with the rest of UBIFS
code.
Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
---
fs/ubifs/debug.c | 33 ++-------------------------------
fs/ubifs/debug.h | 27 +--------------------------
2 files changed, 3 insertions(+), 57 deletions(-)
diff --git a/fs/ubifs/debug.c b/fs/ubifs/debug.c
index 741f939..a159cfd 100644
--- a/fs/ubifs/debug.c
+++ b/fs/ubifs/debug.c
@@ -2718,16 +2718,8 @@ static void cut_data(const void *buf, int len)
p[i] = 0xff;
}
-int dbg_leb_read(struct ubi_volume_desc *desc, int lnum, char *buf, int offset,
- int len, int check)
-{
- if (in_failure_mode(desc))
- return -EROFS;
- return ubi_leb_read(desc, lnum, buf, offset, len, check);
-}
-
int dbg_leb_write(struct ubi_volume_desc *desc, int lnum, const void *buf,
- int offset, int len, int dtype)
+ int offs, int len, int dtype)
{
int err, failing;
@@ -2736,7 +2728,7 @@ int dbg_leb_write(struct ubi_volume_desc *desc, int lnum, const void *buf,
failing = do_fail(desc, lnum, 1);
if (failing)
cut_data(buf, len);
- err = ubi_leb_write(desc, lnum, buf, offset, len, dtype);
+ err = ubi_leb_write(desc, lnum, buf, offs, len, dtype);
if (err)
return err;
if (failing)
@@ -2759,20 +2751,6 @@ int dbg_leb_change(struct ubi_volume_desc *desc, int lnum, const void *buf,
return 0;
}
-int dbg_leb_erase(struct ubi_volume_desc *desc, int lnum)
-{
- int err;
-
- if (do_fail(desc, lnum, 0))
- return -EROFS;
- err = ubi_leb_erase(desc, lnum);
- if (err)
- return err;
- if (do_fail(desc, lnum, 0))
- return -EROFS;
- return 0;
-}
-
int dbg_leb_unmap(struct ubi_volume_desc *desc, int lnum)
{
int err;
@@ -2787,13 +2765,6 @@ int dbg_leb_unmap(struct ubi_volume_desc *desc, int lnum)
return 0;
}
-int dbg_is_mapped(struct ubi_volume_desc *desc, int lnum)
-{
- if (in_failure_mode(desc))
- return -EROFS;
- return ubi_is_mapped(desc, lnum);
-}
-
int dbg_leb_map(struct ubi_volume_desc *desc, int lnum, int dtype)
{
int err;
diff --git a/fs/ubifs/debug.h b/fs/ubifs/debug.h
index 43ec5d1..e1dcfd2 100644
--- a/fs/ubifs/debug.h
+++ b/fs/ubifs/debug.h
@@ -302,44 +302,19 @@ int dbg_check_data_nodes_order(struct ubifs_info *c, struct list_head *head);
int dbg_check_nondata_nodes_order(struct ubifs_info *c, struct list_head *head);
#ifndef UBIFS_DBG_PRESERVE_UBI
-#define ubi_leb_read dbg_leb_read
#define ubi_leb_write dbg_leb_write
#define ubi_leb_change dbg_leb_change
-#define ubi_leb_erase dbg_leb_erase
#define ubi_leb_unmap dbg_leb_unmap
-#define ubi_is_mapped dbg_is_mapped
#define ubi_leb_map dbg_leb_map
#endif
-int dbg_leb_read(struct ubi_volume_desc *desc, int lnum, char *buf, int offset,
- int len, int check);
int dbg_leb_write(struct ubi_volume_desc *desc, int lnum, const void *buf,
- int offset, int len, int dtype);
+ int offs, int len, int dtype);
int dbg_leb_change(struct ubi_volume_desc *desc, int lnum, const void *buf,
int len, int dtype);
-int dbg_leb_erase(struct ubi_volume_desc *desc, int lnum);
int dbg_leb_unmap(struct ubi_volume_desc *desc, int lnum);
-int dbg_is_mapped(struct ubi_volume_desc *desc, int lnum);
int dbg_leb_map(struct ubi_volume_desc *desc, int lnum, int dtype);
-static inline int dbg_read(struct ubi_volume_desc *desc, int lnum, char *buf,
- int offset, int len)
-{
- return dbg_leb_read(desc, lnum, buf, offset, len, 0);
-}
-
-static inline int dbg_write(struct ubi_volume_desc *desc, int lnum,
- const void *buf, int offset, int len)
-{
- return dbg_leb_write(desc, lnum, buf, offset, len, UBI_UNKNOWN);
-}
-
-static inline int dbg_change(struct ubi_volume_desc *desc, int lnum,
- const void *buf, int len)
-{
- return dbg_leb_change(desc, lnum, buf, len, UBI_UNKNOWN);
-}
-
/* Debugfs-related stuff */
int dbg_debugfs_init(void);
void dbg_debugfs_exit(void);
--
1.7.2.3
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [PATCH 22/30] UBIFS: always print stacktrace when switching to R/O mode
2011-06-09 9:04 [PATCH 00/30] UBIFS: latest patches Artem Bityutskiy
` (20 preceding siblings ...)
2011-06-09 9:05 ` [PATCH 21/30] UBIFS: remove unused and unneeded debugging function Artem Bityutskiy
@ 2011-06-09 9:05 ` Artem Bityutskiy
2011-06-09 9:05 ` [PATCH 23/30] UBIFS: introduce more I/O helpers Artem Bityutskiy
` (7 subsequent siblings)
29 siblings, 0 replies; 31+ messages in thread
From: Artem Bityutskiy @ 2011-06-09 9:05 UTC (permalink / raw)
To: linux-mtd
From: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
When switching to R/O mode due to an I/O error, always dump the stack, not only
when debugging is enabled.
Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
---
fs/ubifs/io.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/fs/ubifs/io.c b/fs/ubifs/io.c
index 3be645e..48e1680 100644
--- a/fs/ubifs/io.c
+++ b/fs/ubifs/io.c
@@ -86,7 +86,7 @@ void ubifs_ro_mode(struct ubifs_info *c, int err)
c->no_chk_data_crc = 0;
c->vfs_sb->s_flags |= MS_RDONLY;
ubifs_warn("switched to read-only mode, error %d", err);
- dbg_dump_stack();
+ dump_stack();
}
}
--
1.7.2.3
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [PATCH 23/30] UBIFS: introduce more I/O helpers
2011-06-09 9:04 [PATCH 00/30] UBIFS: latest patches Artem Bityutskiy
` (21 preceding siblings ...)
2011-06-09 9:05 ` [PATCH 22/30] UBIFS: always print stacktrace when switching to R/O mode Artem Bityutskiy
@ 2011-06-09 9:05 ` Artem Bityutskiy
2011-06-09 9:05 ` [PATCH 24/30] UBIFS: switch to ubifs_leb_read Artem Bityutskiy
` (6 subsequent siblings)
29 siblings, 0 replies; 31+ messages in thread
From: Artem Bityutskiy @ 2011-06-09 9:05 UTC (permalink / raw)
To: linux-mtd
From: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
Introduce the following I/O helper functions: 'ubifs_leb_read()',
'ubifs_leb_write()', 'ubifs_leb_change()', 'ubifs_leb_unmap()',
'ubifs_leb_map()', 'ubifs_is_mapped().
The idea is to wrap all UBI I/O functions in order to encapsulate various
assertions and error path handling (error message, stack dump, switching to R/O
mode). And there are some other benefits of this which will be used in the
following patches.
This patch does not switch whole UBIFS to use these functions yet.
Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
---
fs/ubifs/debug.h | 16 +++++++
fs/ubifs/io.c | 117 +++++++++++++++++++++++++++++++++++++++++++++++++++
fs/ubifs/misc.h | 80 -----------------------------------
fs/ubifs/recovery.c | 9 ++--
fs/ubifs/ubifs.h | 13 +++++-
5 files changed, 148 insertions(+), 87 deletions(-)
diff --git a/fs/ubifs/debug.h b/fs/ubifs/debug.h
index e1dcfd2..b0b005b 100644
--- a/fs/ubifs/debug.h
+++ b/fs/ubifs/debug.h
@@ -244,6 +244,10 @@ static inline int dbg_is_tst_rcvry(const struct ubifs_info *c)
{
return !!(ubifs_dbg.tst_rcvry || c->dbg->tst_rcvry);
}
+static inline int dbg_is_power_cut(const struct ubifs_info *c)
+{
+ return !!c->dbg->failure_mode;
+}
int ubifs_debugging_init(struct ubifs_info *c);
void ubifs_debugging_exit(struct ubifs_info *c);
@@ -445,12 +449,24 @@ static inline int
dbg_check_nondata_nodes_order(struct ubifs_info *c,
struct list_head *head) { return 0; }
+static inline int dbg_leb_write(struct ubi_volume_desc *desc,
+ int lnum, const void *buf,
+ int offset, int len, int dtype) { return 0; }
+static inline int dbg_leb_change(struct ubi_volume_desc *desc,
+ int lnum, const void *buf,
+ int len, int dtype) { return 0; }
+static inline int dbg_leb_unmap(struct ubi_volume_desc *desc,
+ int lnum) { return 0; }
+static inline int dbg_leb_map(struct ubi_volume_desc *desc,
+ int lnum, int dtype) { return 0; }
+
static inline int dbg_is_chk_gen(const struct ubifs_info *c) { return 0; }
static inline int dbg_is_chk_index(const struct ubifs_info *c) { return 0; }
static inline int dbg_is_chk_orph(const struct ubifs_info *c) { return 0; }
static inline int dbg_is_chk_lprops(const struct ubifs_info *c) { return 0; }
static inline int dbg_is_chk_fs(const struct ubifs_info *c) { return 0; }
static inline int dbg_is_tst_rcvry(const struct ubifs_info *c) { return 0; }
+static inline int dbg_is_power_cut(const struct ubifs_info *c) { return 0; }
static inline int dbg_debugfs_init(void) { return 0; }
static inline void dbg_debugfs_exit(void) { return; }
diff --git a/fs/ubifs/io.c b/fs/ubifs/io.c
index 48e1680..239899d 100644
--- a/fs/ubifs/io.c
+++ b/fs/ubifs/io.c
@@ -90,6 +90,123 @@ void ubifs_ro_mode(struct ubifs_info *c, int err)
}
}
+/*
+ * Below are simple wrappers over UBI I/O functions which include some
+ * additional checks and UBIFS debugging stuff. See corresponding UBI function
+ * for more information.
+ */
+
+int ubifs_leb_read(const struct ubifs_info *c, int lnum, void *buf, int offs,
+ int len, int even_ebadmsg)
+{
+ int err;
+
+ err = ubi_read(c->ubi, lnum, buf, offs, len);
+ /*
+ * In case of %-EBADMSG print the error message only if the
+ * @even_ebadmsg is true.
+ */
+ if (err && (err != -EBADMSG || even_ebadmsg)) {
+ ubifs_err("reading %d bytes from LEB %d:%d failed, error %d",
+ len, lnum, offs, err);
+ dbg_dump_stack();
+ }
+ return err;
+}
+
+int ubifs_leb_write(struct ubifs_info *c, int lnum, const void *buf, int offs,
+ int len, int dtype)
+{
+ int err;
+
+ ubifs_assert(!c->ro_media && !c->ro_mount);
+ if (c->ro_error)
+ return -EROFS;
+ if (!dbg_is_tst_rcvry(c))
+ err = ubi_leb_write(c->ubi, lnum, buf, offs, len, dtype);
+ else
+ err = dbg_leb_write(c->ubi, lnum, buf, offs, len, dtype);
+ if (err) {
+ ubifs_err("writing %d bytes to LEB %d:%d failed, error %d",
+ len, lnum, offs, err);
+ ubifs_ro_mode(c, err);
+ dbg_dump_stack();
+ }
+ return err;
+}
+
+int ubifs_leb_change(struct ubifs_info *c, int lnum, const void *buf, int len,
+ int dtype)
+{
+ int err;
+
+ ubifs_assert(!c->ro_media && !c->ro_mount);
+ if (c->ro_error)
+ return -EROFS;
+ if (!dbg_is_tst_rcvry(c))
+ err = ubi_leb_change(c->ubi, lnum, buf, len, dtype);
+ else
+ err = dbg_leb_change(c->ubi, lnum, buf, len, dtype);
+ if (err) {
+ ubifs_err("changing %d bytes in LEB %d failed, error %d",
+ len, lnum, err);
+ ubifs_ro_mode(c, err);
+ dbg_dump_stack();
+ }
+ return err;
+}
+
+int ubifs_leb_unmap(struct ubifs_info *c, int lnum)
+{
+ int err;
+
+ ubifs_assert(!c->ro_media && !c->ro_mount);
+ if (c->ro_error)
+ return -EROFS;
+ if (!dbg_is_tst_rcvry(c))
+ err = ubi_leb_unmap(c->ubi, lnum);
+ else
+ err = dbg_leb_unmap(c->ubi, lnum);
+ if (err) {
+ ubifs_err("unmap LEB %d failed, error %d", lnum, err);
+ ubifs_ro_mode(c, err);
+ dbg_dump_stack();
+ }
+ return err;
+}
+
+int ubifs_leb_map(struct ubifs_info *c, int lnum, int dtype)
+{
+ int err;
+
+ ubifs_assert(!c->ro_media && !c->ro_mount);
+ if (c->ro_error)
+ return -EROFS;
+ if (!dbg_is_tst_rcvry(c))
+ err = ubi_leb_map(c->ubi, lnum, dtype);
+ else
+ err = dbg_leb_map(c->ubi, lnum, dtype);
+ if (err) {
+ ubifs_err("mapping LEB %d failed, error %d", lnum, err);
+ ubifs_ro_mode(c, err);
+ dbg_dump_stack();
+ }
+ return err;
+}
+
+int ubifs_is_mapped(const struct ubifs_info *c, int lnum)
+{
+ int err;
+
+ err = ubi_is_mapped(c->ubi, lnum);
+ if (err < 0) {
+ ubifs_err("ubi_is_mapped failed for LEB %d, error %d",
+ lnum, err);
+ dbg_dump_stack();
+ }
+ return err;
+}
+
/**
* ubifs_check_node - check node.
* @c: UBIFS file-system description object
diff --git a/fs/ubifs/misc.h b/fs/ubifs/misc.h
index 160cd90..ee7cb5e 100644
--- a/fs/ubifs/misc.h
+++ b/fs/ubifs/misc.h
@@ -145,86 +145,6 @@ static inline int ubifs_wbuf_sync(struct ubifs_wbuf *wbuf)
}
/**
- * ubifs_leb_unmap - unmap an LEB.
- * @c: UBIFS file-system description object
- * @lnum: LEB number to unmap
- *
- * This function returns %0 on success and a negative error code on failure.
- */
-static inline int ubifs_leb_unmap(const struct ubifs_info *c, int lnum)
-{
- int err;
-
- ubifs_assert(!c->ro_media && !c->ro_mount);
- if (c->ro_error)
- return -EROFS;
- err = ubi_leb_unmap(c->ubi, lnum);
- if (err) {
- ubifs_err("unmap LEB %d failed, error %d", lnum, err);
- return err;
- }
-
- return 0;
-}
-
-/**
- * ubifs_leb_write - write to a LEB.
- * @c: UBIFS file-system description object
- * @lnum: LEB number to write
- * @buf: buffer to write from
- * @offs: offset within LEB to write to
- * @len: length to write
- * @dtype: data type
- *
- * This function returns %0 on success and a negative error code on failure.
- */
-static inline int ubifs_leb_write(const struct ubifs_info *c, int lnum,
- const void *buf, int offs, int len, int dtype)
-{
- int err;
-
- ubifs_assert(!c->ro_media && !c->ro_mount);
- if (c->ro_error)
- return -EROFS;
- err = ubi_leb_write(c->ubi, lnum, buf, offs, len, dtype);
- if (err) {
- ubifs_err("writing %d bytes at %d:%d, error %d",
- len, lnum, offs, err);
- return err;
- }
-
- return 0;
-}
-
-/**
- * ubifs_leb_change - atomic LEB change.
- * @c: UBIFS file-system description object
- * @lnum: LEB number to write
- * @buf: buffer to write from
- * @len: length to write
- * @dtype: data type
- *
- * This function returns %0 on success and a negative error code on failure.
- */
-static inline int ubifs_leb_change(const struct ubifs_info *c, int lnum,
- const void *buf, int len, int dtype)
-{
- int err;
-
- ubifs_assert(!c->ro_media && !c->ro_mount);
- if (c->ro_error)
- return -EROFS;
- err = ubi_leb_change(c->ubi, lnum, buf, len, dtype);
- if (err) {
- ubifs_err("changing %d bytes in LEB %d, error %d",
- len, lnum, err);
- return err;
- }
-
- return 0;
-}
-
-/**
* ubifs_encode_dev - encode device node IDs.
* @dev: UBIFS device node information
* @rdev: device IDs to encode
diff --git a/fs/ubifs/recovery.c b/fs/ubifs/recovery.c
index 783d8e0..c591549 100644
--- a/fs/ubifs/recovery.c
+++ b/fs/ubifs/recovery.c
@@ -919,8 +919,7 @@ struct ubifs_scan_leb *ubifs_recover_log_leb(struct ubifs_info *c, int lnum,
*
* This function returns %0 on success and a negative error code on failure.
*/
-static int recover_head(const struct ubifs_info *c, int lnum, int offs,
- void *sbuf)
+static int recover_head(struct ubifs_info *c, int lnum, int offs, void *sbuf)
{
int len = c->max_write_size, err;
@@ -962,7 +961,7 @@ static int recover_head(const struct ubifs_info *c, int lnum, int offs,
*
* This function returns %0 on success and a negative error code on failure.
*/
-int ubifs_recover_inl_heads(const struct ubifs_info *c, void *sbuf)
+int ubifs_recover_inl_heads(struct ubifs_info *c, void *sbuf)
{
int err;
@@ -993,7 +992,7 @@ int ubifs_recover_inl_heads(const struct ubifs_info *c, void *sbuf)
*
* This function returns %0 on success and a negative error code on failure.
*/
-static int clean_an_unclean_leb(const struct ubifs_info *c,
+static int clean_an_unclean_leb(struct ubifs_info *c,
struct ubifs_unclean_leb *ucleb, void *sbuf)
{
int err, lnum = ucleb->lnum, offs = 0, len = ucleb->endpt, quiet = 1;
@@ -1089,7 +1088,7 @@ static int clean_an_unclean_leb(const struct ubifs_info *c,
*
* This function returns %0 on success and a negative error code on failure.
*/
-int ubifs_clean_lebs(const struct ubifs_info *c, void *sbuf)
+int ubifs_clean_lebs(struct ubifs_info *c, void *sbuf)
{
dbg_rcvry("recovery");
while (!list_empty(&c->unclean_leb_list)) {
diff --git a/fs/ubifs/ubifs.h b/fs/ubifs/ubifs.h
index 3304aad..702b792 100644
--- a/fs/ubifs/ubifs.h
+++ b/fs/ubifs/ubifs.h
@@ -1468,6 +1468,15 @@ extern struct ubifs_compressor *ubifs_compressors[UBIFS_COMPR_TYPES_CNT];
/* io.c */
void ubifs_ro_mode(struct ubifs_info *c, int err);
+int ubifs_leb_read(const struct ubifs_info *c, int lnum, void *buf, int offs,
+ int len, int even_ebadmsg);
+int ubifs_leb_write(struct ubifs_info *c, int lnum, const void *buf, int offs,
+ int len, int dtype);
+int ubifs_leb_change(struct ubifs_info *c, int lnum, const void *buf, int len,
+ int dtype);
+int ubifs_leb_unmap(struct ubifs_info *c, int lnum);
+int ubifs_leb_map(struct ubifs_info *c, int lnum, int dtype);
+int ubifs_is_mapped(const struct ubifs_info *c, int lnum);
int ubifs_wbuf_write_nolock(struct ubifs_wbuf *wbuf, void *buf, int len);
int ubifs_wbuf_seek_nolock(struct ubifs_wbuf *wbuf, int lnum, int offs,
int dtype);
@@ -1747,8 +1756,8 @@ struct ubifs_scan_leb *ubifs_recover_leb(struct ubifs_info *c, int lnum,
int offs, void *sbuf, int jhead);
struct ubifs_scan_leb *ubifs_recover_log_leb(struct ubifs_info *c, int lnum,
int offs, void *sbuf);
-int ubifs_recover_inl_heads(const struct ubifs_info *c, void *sbuf);
-int ubifs_clean_lebs(const struct ubifs_info *c, void *sbuf);
+int ubifs_recover_inl_heads(struct ubifs_info *c, void *sbuf);
+int ubifs_clean_lebs(struct ubifs_info *c, void *sbuf);
int ubifs_rcvry_gc_commit(struct ubifs_info *c);
int ubifs_recover_size_accum(struct ubifs_info *c, union ubifs_key *key,
int deletion, loff_t new_size);
--
1.7.2.3
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [PATCH 24/30] UBIFS: switch to ubifs_leb_read
2011-06-09 9:04 [PATCH 00/30] UBIFS: latest patches Artem Bityutskiy
` (22 preceding siblings ...)
2011-06-09 9:05 ` [PATCH 23/30] UBIFS: introduce more I/O helpers Artem Bityutskiy
@ 2011-06-09 9:05 ` Artem Bityutskiy
2011-06-09 9:05 ` [PATCH 25/30] UBIFS: switch to ubifs_leb_write Artem Bityutskiy
` (5 subsequent siblings)
29 siblings, 0 replies; 31+ messages in thread
From: Artem Bityutskiy @ 2011-06-09 9:05 UTC (permalink / raw)
To: linux-mtd
From: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
Instead of using 'ubi_read()' function directly, used the 'ubifs_leb_read()'
helper function instead. This allows to get rid of several redundant error
messages and make sure that we always have a stack dump on read errors.
Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
---
fs/ubifs/io.c | 15 ++++-----------
fs/ubifs/lpt.c | 17 +++++++++--------
fs/ubifs/lpt_commit.c | 23 +++++++++++------------
fs/ubifs/recovery.c | 17 +++++++++--------
fs/ubifs/replay.c | 3 +--
fs/ubifs/sb.c | 2 +-
fs/ubifs/scan.c | 2 +-
fs/ubifs/tnc.c | 8 ++++----
8 files changed, 40 insertions(+), 47 deletions(-)
diff --git a/fs/ubifs/io.c b/fs/ubifs/io.c
index 239899d..f58f11b 100644
--- a/fs/ubifs/io.c
+++ b/fs/ubifs/io.c
@@ -941,13 +941,9 @@ int ubifs_read_node_wbuf(struct ubifs_wbuf *wbuf, void *buf, int type, int len,
if (rlen > 0) {
/* Read everything that goes before write-buffer */
- err = ubi_read(c->ubi, lnum, buf, offs, rlen);
- if (err && err != -EBADMSG) {
- ubifs_err("failed to read node %d from LEB %d:%d, "
- "error %d", type, lnum, offs, err);
- dbg_dump_stack();
+ err = ubifs_leb_read(c, lnum, buf, offs, rlen, 0);
+ if (err && err != -EBADMSG)
return err;
- }
}
if (type != ch->node_type) {
@@ -1002,12 +998,9 @@ int ubifs_read_node(const struct ubifs_info *c, void *buf, int type, int len,
ubifs_assert(!(offs & 7) && offs < c->leb_size);
ubifs_assert(type >= 0 && type < UBIFS_NODE_TYPES_CNT);
- err = ubi_read(c->ubi, lnum, buf, offs, len);
- if (err && err != -EBADMSG) {
- ubifs_err("cannot read node %d from LEB %d:%d, error %d",
- type, lnum, offs, err);
+ err = ubifs_leb_read(c, lnum, buf, offs, len, 0);
+ if (err && err != -EBADMSG)
return err;
- }
if (type != ch->node_type) {
ubifs_err("bad node type (%d but expected %d)",
diff --git a/fs/ubifs/lpt.c b/fs/ubifs/lpt.c
index ab91ca6..8b9ee9f 100644
--- a/fs/ubifs/lpt.c
+++ b/fs/ubifs/lpt.c
@@ -1222,7 +1222,7 @@ int ubifs_read_nnode(struct ubifs_info *c, struct ubifs_nnode *parent, int iip)
if (c->big_lpt)
nnode->num = calc_nnode_num_from_parent(c, parent, iip);
} else {
- err = ubi_read(c->ubi, lnum, buf, offs, c->nnode_sz);
+ err = ubifs_leb_read(c, lnum, buf, offs, c->nnode_sz, 1);
if (err)
goto out;
err = ubifs_unpack_nnode(c, buf, nnode);
@@ -1291,7 +1291,7 @@ static int read_pnode(struct ubifs_info *c, struct ubifs_nnode *parent, int iip)
lprops->flags = ubifs_categorize_lprops(c, lprops);
}
} else {
- err = ubi_read(c->ubi, lnum, buf, offs, c->pnode_sz);
+ err = ubifs_leb_read(c, lnum, buf, offs, c->pnode_sz, 1);
if (err)
goto out;
err = unpack_pnode(c, buf, pnode);
@@ -1333,7 +1333,7 @@ static int read_ltab(struct ubifs_info *c)
buf = vmalloc(c->ltab_sz);
if (!buf)
return -ENOMEM;
- err = ubi_read(c->ubi, c->ltab_lnum, buf, c->ltab_offs, c->ltab_sz);
+ err = ubifs_leb_read(c, c->ltab_lnum, buf, c->ltab_offs, c->ltab_sz, 1);
if (err)
goto out;
err = unpack_ltab(c, buf);
@@ -1356,7 +1356,8 @@ static int read_lsave(struct ubifs_info *c)
buf = vmalloc(c->lsave_sz);
if (!buf)
return -ENOMEM;
- err = ubi_read(c->ubi, c->lsave_lnum, buf, c->lsave_offs, c->lsave_sz);
+ err = ubifs_leb_read(c, c->lsave_lnum, buf, c->lsave_offs,
+ c->lsave_sz, 1);
if (err)
goto out;
err = unpack_lsave(c, buf);
@@ -1816,8 +1817,8 @@ static struct ubifs_nnode *scan_get_nnode(struct ubifs_info *c,
if (c->big_lpt)
nnode->num = calc_nnode_num_from_parent(c, parent, iip);
} else {
- err = ubi_read(c->ubi, branch->lnum, buf, branch->offs,
- c->nnode_sz);
+ err = ubifs_leb_read(c, branch->lnum, buf, branch->offs,
+ c->nnode_sz, 1);
if (err)
return ERR_PTR(err);
err = ubifs_unpack_nnode(c, buf, nnode);
@@ -1885,8 +1886,8 @@ static struct ubifs_pnode *scan_get_pnode(struct ubifs_info *c,
ubifs_assert(branch->lnum >= c->lpt_first &&
branch->lnum <= c->lpt_last);
ubifs_assert(branch->offs >= 0 && branch->offs < c->leb_size);
- err = ubi_read(c->ubi, branch->lnum, buf, branch->offs,
- c->pnode_sz);
+ err = ubifs_leb_read(c, branch->lnum, buf, branch->offs,
+ c->pnode_sz, 1);
if (err)
return ERR_PTR(err);
err = unpack_pnode(c, buf, pnode);
diff --git a/fs/ubifs/lpt_commit.c b/fs/ubifs/lpt_commit.c
index f13addf..cddd6bd 100644
--- a/fs/ubifs/lpt_commit.c
+++ b/fs/ubifs/lpt_commit.c
@@ -1161,11 +1161,11 @@ static int lpt_gc_lnum(struct ubifs_info *c, int lnum)
void *buf = c->lpt_buf;
dbg_lp("LEB %d", lnum);
- err = ubi_read(c->ubi, lnum, buf, 0, c->leb_size);
- if (err) {
- ubifs_err("cannot read LEB %d, error %d", lnum, err);
+
+ err = ubifs_leb_read(c, lnum, buf, 0, c->leb_size, 1);
+ if (err)
return err;
- }
+
while (1) {
if (!is_a_node(c, buf, len)) {
int pad_len;
@@ -1651,11 +1651,11 @@ static int dbg_check_ltab_lnum(struct ubifs_info *c, int lnum)
}
dbg_lp("LEB %d", lnum);
- err = ubi_read(c->ubi, lnum, buf, 0, c->leb_size);
- if (err) {
- dbg_msg("ubi_read failed, LEB %d, error %d", lnum, err);
+
+ err = ubifs_leb_read(c, lnum, buf, 0, c->leb_size, 1);
+ if (err)
goto out;
- }
+
while (1) {
if (!is_a_node(c, p, len)) {
int i, pad_len;
@@ -1902,11 +1902,10 @@ static void dump_lpt_leb(const struct ubifs_info *c, int lnum)
return;
}
- err = ubi_read(c->ubi, lnum, buf, 0, c->leb_size);
- if (err) {
- ubifs_err("cannot read LEB %d, error %d", lnum, err);
+ err = ubifs_leb_read(c, lnum, buf, 0, c->leb_size, 1);
+ if (err)
goto out;
- }
+
while (1) {
offs = c->leb_size - len;
if (!is_a_node(c, p, len)) {
diff --git a/fs/ubifs/recovery.c b/fs/ubifs/recovery.c
index c591549..f28070c 100644
--- a/fs/ubifs/recovery.c
+++ b/fs/ubifs/recovery.c
@@ -117,7 +117,7 @@ static int get_master_node(const struct ubifs_info *c, int lnum, void **pbuf,
if (!sbuf)
return -ENOMEM;
- err = ubi_read(c->ubi, lnum, sbuf, 0, c->leb_size);
+ err = ubifs_leb_read(c, lnum, sbuf, 0, c->leb_size, 0);
if (err && err != -EBADMSG)
goto out_free;
@@ -539,8 +539,8 @@ static int fix_unclean_leb(struct ubifs_info *c, struct ubifs_scan_leb *sleb,
int len = ALIGN(endpt, c->min_io_size);
if (start) {
- err = ubi_read(c->ubi, lnum, sleb->buf, 0,
- start);
+ err = ubifs_leb_read(c, lnum, sleb->buf, 0,
+ start, 1);
if (err)
return err;
}
@@ -819,7 +819,8 @@ static int get_cs_sqnum(struct ubifs_info *c, int lnum, int offs,
return -ENOMEM;
if (c->leb_size - offs < UBIFS_CS_NODE_SZ)
goto out_err;
- err = ubi_read(c->ubi, lnum, (void *)cs_node, offs, UBIFS_CS_NODE_SZ);
+ err = ubifs_leb_read(c, lnum, (void *)cs_node, offs,
+ UBIFS_CS_NODE_SZ, 0);
if (err && err != -EBADMSG)
goto out_free;
ret = ubifs_scan_a_node(c, cs_node, UBIFS_CS_NODE_SZ, lnum, offs, 0);
@@ -930,12 +931,12 @@ static int recover_head(struct ubifs_info *c, int lnum, int offs, void *sbuf)
return 0;
/* Read at the head location and check it is empty flash */
- err = ubi_read(c->ubi, lnum, sbuf, offs, len);
+ err = ubifs_leb_read(c, lnum, sbuf, offs, len, 1);
if (err || !is_empty(sbuf, len)) {
dbg_rcvry("cleaning head at %d:%d", lnum, offs);
if (offs == 0)
return ubifs_leb_unmap(c, lnum);
- err = ubi_read(c->ubi, lnum, sbuf, 0, offs);
+ err = ubifs_leb_read(c, lnum, sbuf, 0, offs, 1);
if (err)
return err;
return ubi_leb_change(c->ubi, lnum, sbuf, offs, UBI_UNKNOWN);
@@ -1008,7 +1009,7 @@ static int clean_an_unclean_leb(struct ubifs_info *c,
return 0;
}
- err = ubi_read(c->ubi, lnum, buf, offs, len);
+ err = ubifs_leb_read(c, lnum, buf, offs, len, 0);
if (err && err != -EBADMSG)
return err;
@@ -1453,7 +1454,7 @@ static int fix_size_in_place(struct ubifs_info *c, struct size_entry *e)
if (i_size >= e->d_size)
return 0;
/* Read the LEB */
- err = ubi_read(c->ubi, lnum, c->sbuf, 0, c->leb_size);
+ err = ubifs_leb_read(c, lnum, c->sbuf, 0, c->leb_size, 1);
if (err)
goto out;
/* Change the size field and recalculate the CRC */
diff --git a/fs/ubifs/replay.c b/fs/ubifs/replay.c
index 5e97161..ccabaf1 100644
--- a/fs/ubifs/replay.c
+++ b/fs/ubifs/replay.c
@@ -523,8 +523,7 @@ static int is_last_bud(struct ubifs_info *c, struct ubifs_bud *bud)
if (!list_is_last(&next->list, &jh->buds_list))
return 0;
- err = ubi_read(c->ubi, next->lnum, (char *)&data,
- next->start, 4);
+ err = ubifs_leb_read(c, next->lnum, (char *)&data, next->start, 4, 1);
if (err)
return 0;
diff --git a/fs/ubifs/sb.c b/fs/ubifs/sb.c
index c606f01..701dccc 100644
--- a/fs/ubifs/sb.c
+++ b/fs/ubifs/sb.c
@@ -678,7 +678,7 @@ static int fixup_leb(struct ubifs_info *c, int lnum, int len)
}
dbg_mnt("fixup LEB %d, data len %d", lnum, len);
- err = ubi_read(c->ubi, lnum, c->sbuf, 0, len);
+ err = ubifs_leb_read(c, lnum, c->sbuf, 0, len, 1);
if (err)
return err;
diff --git a/fs/ubifs/scan.c b/fs/ubifs/scan.c
index c7df916..37383e8 100644
--- a/fs/ubifs/scan.c
+++ b/fs/ubifs/scan.c
@@ -148,7 +148,7 @@ struct ubifs_scan_leb *ubifs_start_scan(const struct ubifs_info *c, int lnum,
INIT_LIST_HEAD(&sleb->nodes);
sleb->buf = sbuf;
- err = ubi_read(c->ubi, lnum, sbuf + offs, offs, c->leb_size - offs);
+ err = ubifs_leb_read(c, lnum, sbuf + offs, offs, c->leb_size - offs, 0);
if (err && err != -EBADMSG) {
ubifs_err("cannot read %d bytes from LEB %d:%d,"
" error %d", c->leb_size - offs, lnum, offs, err);
diff --git a/fs/ubifs/tnc.c b/fs/ubifs/tnc.c
index 526b63c..0667386 100644
--- a/fs/ubifs/tnc.c
+++ b/fs/ubifs/tnc.c
@@ -462,7 +462,7 @@ static int try_read_node(const struct ubifs_info *c, void *buf, int type,
dbg_io("LEB %d:%d, %s, length %d", lnum, offs, dbg_ntype(type), len);
- err = ubi_read(c->ubi, lnum, buf, offs, len);
+ err = ubifs_leb_read(c, lnum, buf, offs, len, 1);
if (err) {
ubifs_err("cannot read node type %d from LEB %d:%d, error %d",
type, lnum, offs, err);
@@ -1666,7 +1666,7 @@ static int read_wbuf(struct ubifs_wbuf *wbuf, void *buf, int len, int lnum,
if (!overlap) {
/* We may safely unlock the write-buffer and read the data */
spin_unlock(&wbuf->lock);
- return ubi_read(c->ubi, lnum, buf, offs, len);
+ return ubifs_leb_read(c, lnum, buf, offs, len, 0);
}
/* Don't read under wbuf */
@@ -1680,7 +1680,7 @@ static int read_wbuf(struct ubifs_wbuf *wbuf, void *buf, int len, int lnum,
if (rlen > 0)
/* Read everything that goes before write-buffer */
- return ubi_read(c->ubi, lnum, buf, offs, rlen);
+ return ubifs_leb_read(c, lnum, buf, offs, rlen, 0);
return 0;
}
@@ -1767,7 +1767,7 @@ int ubifs_tnc_bulk_read(struct ubifs_info *c, struct bu_info *bu)
if (wbuf)
err = read_wbuf(wbuf, bu->buf, len, lnum, offs);
else
- err = ubi_read(c->ubi, lnum, bu->buf, offs, len);
+ err = ubifs_leb_read(c, lnum, bu->buf, offs, len, 0);
/* Check for a race with GC */
if (maybe_leb_gced(c, lnum, bu->gc_seq))
--
1.7.2.3
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [PATCH 25/30] UBIFS: switch to ubifs_leb_write
2011-06-09 9:04 [PATCH 00/30] UBIFS: latest patches Artem Bityutskiy
` (23 preceding siblings ...)
2011-06-09 9:05 ` [PATCH 24/30] UBIFS: switch to ubifs_leb_read Artem Bityutskiy
@ 2011-06-09 9:05 ` Artem Bityutskiy
2011-06-09 9:05 ` [PATCH 26/30] UBIFS: switch to I/O helpers Artem Bityutskiy
` (4 subsequent siblings)
29 siblings, 0 replies; 31+ messages in thread
From: Artem Bityutskiy @ 2011-06-09 9:05 UTC (permalink / raw)
To: linux-mtd
From: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
Stop using 'ubi_leb_write()' directly and switch to the 'ubifs_leb_write()'
helper.
Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
---
fs/ubifs/io.c | 36 ++++++++++++++----------------------
1 files changed, 14 insertions(+), 22 deletions(-)
diff --git a/fs/ubifs/io.c b/fs/ubifs/io.c
index f58f11b..a0c5fb4 100644
--- a/fs/ubifs/io.c
+++ b/fs/ubifs/io.c
@@ -523,14 +523,10 @@ int ubifs_wbuf_sync_nolock(struct ubifs_wbuf *wbuf)
dirt = sync_len - wbuf->used;
if (dirt)
ubifs_pad(c, wbuf->buf + wbuf->used, dirt);
- err = ubi_leb_write(c->ubi, wbuf->lnum, wbuf->buf, wbuf->offs,
- sync_len, wbuf->dtype);
- if (err) {
- ubifs_err("cannot write %d bytes to LEB %d:%d",
- sync_len, wbuf->lnum, wbuf->offs);
- dbg_dump_stack();
+ err = ubifs_leb_write(c, wbuf->lnum, wbuf->buf, wbuf->offs, sync_len,
+ wbuf->dtype);
+ if (err)
return err;
- }
spin_lock(&wbuf->lock);
wbuf->offs += sync_len;
@@ -722,9 +718,9 @@ int ubifs_wbuf_write_nolock(struct ubifs_wbuf *wbuf, void *buf, int len)
if (aligned_len == wbuf->avail) {
dbg_io("flush jhead %s wbuf to LEB %d:%d",
dbg_jhead(wbuf->jhead), wbuf->lnum, wbuf->offs);
- err = ubi_leb_write(c->ubi, wbuf->lnum, wbuf->buf,
- wbuf->offs, wbuf->size,
- wbuf->dtype);
+ err = ubifs_leb_write(c, wbuf->lnum, wbuf->buf,
+ wbuf->offs, wbuf->size,
+ wbuf->dtype);
if (err)
goto out;
@@ -759,8 +755,8 @@ int ubifs_wbuf_write_nolock(struct ubifs_wbuf *wbuf, void *buf, int len)
dbg_io("flush jhead %s wbuf to LEB %d:%d",
dbg_jhead(wbuf->jhead), wbuf->lnum, wbuf->offs);
memcpy(wbuf->buf + wbuf->used, buf, wbuf->avail);
- err = ubi_leb_write(c->ubi, wbuf->lnum, wbuf->buf, wbuf->offs,
- wbuf->size, wbuf->dtype);
+ err = ubifs_leb_write(c, wbuf->lnum, wbuf->buf, wbuf->offs,
+ wbuf->size, wbuf->dtype);
if (err)
goto out;
@@ -778,8 +774,8 @@ int ubifs_wbuf_write_nolock(struct ubifs_wbuf *wbuf, void *buf, int len)
*/
dbg_io("write %d bytes to LEB %d:%d",
wbuf->size, wbuf->lnum, wbuf->offs);
- err = ubi_leb_write(c->ubi, wbuf->lnum, buf, wbuf->offs,
- wbuf->size, wbuf->dtype);
+ err = ubifs_leb_write(c, wbuf->lnum, buf, wbuf->offs,
+ wbuf->size, wbuf->dtype);
if (err)
goto out;
@@ -800,8 +796,8 @@ int ubifs_wbuf_write_nolock(struct ubifs_wbuf *wbuf, void *buf, int len)
n <<= c->max_write_shift;
dbg_io("write %d bytes to LEB %d:%d", n, wbuf->lnum,
wbuf->offs);
- err = ubi_leb_write(c->ubi, wbuf->lnum, buf + written,
- wbuf->offs, n, wbuf->dtype);
+ err = ubifs_leb_write(c, wbuf->lnum, buf + written,
+ wbuf->offs, n, wbuf->dtype);
if (err)
goto out;
wbuf->offs += n;
@@ -883,13 +879,9 @@ int ubifs_write_node(struct ubifs_info *c, void *buf, int len, int lnum,
return -EROFS;
ubifs_prepare_node(c, buf, len, 1);
- err = ubi_leb_write(c->ubi, lnum, buf, offs, buf_len, dtype);
- if (err) {
- ubifs_err("cannot write %d bytes to LEB %d:%d, error %d",
- buf_len, lnum, offs, err);
+ err = ubifs_leb_write(c, lnum, buf, offs, buf_len, dtype);
+ if (err)
dbg_dump_node(c, buf);
- dbg_dump_stack();
- }
return err;
}
--
1.7.2.3
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [PATCH 26/30] UBIFS: switch to I/O helpers
2011-06-09 9:04 [PATCH 00/30] UBIFS: latest patches Artem Bityutskiy
` (24 preceding siblings ...)
2011-06-09 9:05 ` [PATCH 25/30] UBIFS: switch to ubifs_leb_write Artem Bityutskiy
@ 2011-06-09 9:05 ` Artem Bityutskiy
2011-06-09 9:05 ` [PATCH 27/30] UBIFS: stop re-defining UBI operations Artem Bityutskiy
` (3 subsequent siblings)
29 siblings, 0 replies; 31+ messages in thread
From: Artem Bityutskiy @ 2011-06-09 9:05 UTC (permalink / raw)
To: linux-mtd
From: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
Switch the rest of direct UBI calls to UBIFS helper functions.
Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
---
fs/ubifs/log.c | 4 +---
fs/ubifs/lpt.c | 16 ++++++++--------
fs/ubifs/recovery.c | 14 +++++++-------
fs/ubifs/sb.c | 4 ++--
fs/ubifs/super.c | 2 +-
5 files changed, 19 insertions(+), 21 deletions(-)
diff --git a/fs/ubifs/log.c b/fs/ubifs/log.c
index fabfb53..f9fd068 100644
--- a/fs/ubifs/log.c
+++ b/fs/ubifs/log.c
@@ -262,7 +262,7 @@ int ubifs_add_bud_to_log(struct ubifs_info *c, int jhead, int lnum, int offs)
* an unclean reboot, because the target LEB might have been
* unmapped, but not yet physically erased.
*/
- err = ubi_leb_map(c->ubi, bud->lnum, UBI_SHORTTERM);
+ err = ubifs_leb_map(c, bud->lnum, UBI_SHORTTERM);
if (err)
goto out_unlock;
}
@@ -283,8 +283,6 @@ int ubifs_add_bud_to_log(struct ubifs_info *c, int jhead, int lnum, int offs)
return 0;
out_unlock:
- if (err != -EAGAIN)
- ubifs_ro_mode(c, err);
mutex_unlock(&c->log_mutex);
kfree(ref);
kfree(bud);
diff --git a/fs/ubifs/lpt.c b/fs/ubifs/lpt.c
index 8b9ee9f..6189c74 100644
--- a/fs/ubifs/lpt.c
+++ b/fs/ubifs/lpt.c
@@ -701,8 +701,8 @@ int ubifs_create_dflt_lpt(struct ubifs_info *c, int *main_lebs, int lpt_first,
alen = ALIGN(len, c->min_io_size);
set_ltab(c, lnum, c->leb_size - alen, alen - len);
memset(p, 0xff, alen - len);
- err = ubi_leb_change(c->ubi, lnum++, buf, alen,
- UBI_SHORTTERM);
+ err = ubifs_leb_change(c, lnum++, buf, alen,
+ UBI_SHORTTERM);
if (err)
goto out;
p = buf;
@@ -732,8 +732,8 @@ int ubifs_create_dflt_lpt(struct ubifs_info *c, int *main_lebs, int lpt_first,
set_ltab(c, lnum, c->leb_size - alen,
alen - len);
memset(p, 0xff, alen - len);
- err = ubi_leb_change(c->ubi, lnum++, buf, alen,
- UBI_SHORTTERM);
+ err = ubifs_leb_change(c, lnum++, buf, alen,
+ UBI_SHORTTERM);
if (err)
goto out;
p = buf;
@@ -780,8 +780,8 @@ int ubifs_create_dflt_lpt(struct ubifs_info *c, int *main_lebs, int lpt_first,
alen = ALIGN(len, c->min_io_size);
set_ltab(c, lnum, c->leb_size - alen, alen - len);
memset(p, 0xff, alen - len);
- err = ubi_leb_change(c->ubi, lnum++, buf, alen,
- UBI_SHORTTERM);
+ err = ubifs_leb_change(c, lnum++, buf, alen,
+ UBI_SHORTTERM);
if (err)
goto out;
p = buf;
@@ -806,7 +806,7 @@ int ubifs_create_dflt_lpt(struct ubifs_info *c, int *main_lebs, int lpt_first,
alen = ALIGN(len, c->min_io_size);
set_ltab(c, lnum, c->leb_size - alen, alen - len);
memset(p, 0xff, alen - len);
- err = ubi_leb_change(c->ubi, lnum++, buf, alen, UBI_SHORTTERM);
+ err = ubifs_leb_change(c, lnum++, buf, alen, UBI_SHORTTERM);
if (err)
goto out;
p = buf;
@@ -826,7 +826,7 @@ int ubifs_create_dflt_lpt(struct ubifs_info *c, int *main_lebs, int lpt_first,
/* Write remaining buffer */
memset(p, 0xff, alen - len);
- err = ubi_leb_change(c->ubi, lnum, buf, alen, UBI_SHORTTERM);
+ err = ubifs_leb_change(c, lnum, buf, alen, UBI_SHORTTERM);
if (err)
goto out;
diff --git a/fs/ubifs/recovery.c b/fs/ubifs/recovery.c
index f28070c..51bcf42 100644
--- a/fs/ubifs/recovery.c
+++ b/fs/ubifs/recovery.c
@@ -213,10 +213,10 @@ static int write_rcvrd_mst_node(struct ubifs_info *c,
mst->flags |= cpu_to_le32(UBIFS_MST_RCVRY);
ubifs_prepare_node(c, mst, UBIFS_MST_NODE_SZ, 1);
- err = ubi_leb_change(c->ubi, lnum, mst, sz, UBI_SHORTTERM);
+ err = ubifs_leb_change(c, lnum, mst, sz, UBI_SHORTTERM);
if (err)
goto out;
- err = ubi_leb_change(c->ubi, lnum + 1, mst, sz, UBI_SHORTTERM);
+ err = ubifs_leb_change(c, lnum + 1, mst, sz, UBI_SHORTTERM);
if (err)
goto out;
out:
@@ -554,8 +554,8 @@ static int fix_unclean_leb(struct ubifs_info *c, struct ubifs_scan_leb *sleb,
ubifs_pad(c, buf, pad_len);
}
}
- err = ubi_leb_change(c->ubi, lnum, sleb->buf, len,
- UBI_UNKNOWN);
+ err = ubifs_leb_change(c, lnum, sleb->buf, len,
+ UBI_UNKNOWN);
if (err)
return err;
}
@@ -939,7 +939,7 @@ static int recover_head(struct ubifs_info *c, int lnum, int offs, void *sbuf)
err = ubifs_leb_read(c, lnum, sbuf, 0, offs, 1);
if (err)
return err;
- return ubi_leb_change(c->ubi, lnum, sbuf, offs, UBI_UNKNOWN);
+ return ubifs_leb_change(c, lnum, sbuf, offs, UBI_UNKNOWN);
}
return 0;
@@ -1069,7 +1069,7 @@ static int clean_an_unclean_leb(struct ubifs_info *c,
}
/* Write back the LEB atomically */
- err = ubi_leb_change(c->ubi, lnum, sbuf, len, UBI_UNKNOWN);
+ err = ubifs_leb_change(c, lnum, sbuf, len, UBI_UNKNOWN);
if (err)
return err;
@@ -1470,7 +1470,7 @@ static int fix_size_in_place(struct ubifs_info *c, struct size_entry *e)
len -= 1;
len = ALIGN(len + 1, c->min_io_size);
/* Atomically write the fixed LEB back again */
- err = ubi_leb_change(c->ubi, lnum, c->sbuf, len, UBI_UNKNOWN);
+ err = ubifs_leb_change(c, lnum, c->sbuf, len, UBI_UNKNOWN);
if (err)
goto out;
dbg_rcvry("inode %lu at %d:%d size %lld -> %lld",
diff --git a/fs/ubifs/sb.c b/fs/ubifs/sb.c
index 701dccc..93d938a 100644
--- a/fs/ubifs/sb.c
+++ b/fs/ubifs/sb.c
@@ -674,7 +674,7 @@ static int fixup_leb(struct ubifs_info *c, int lnum, int len)
if (len == 0) {
dbg_mnt("unmap empty LEB %d", lnum);
- return ubi_leb_unmap(c->ubi, lnum);
+ return ubifs_leb_unmap(c, lnum);
}
dbg_mnt("fixup LEB %d, data len %d", lnum, len);
@@ -682,7 +682,7 @@ static int fixup_leb(struct ubifs_info *c, int lnum, int len)
if (err)
return err;
- return ubi_leb_change(c->ubi, lnum, c->sbuf, len, UBI_UNKNOWN);
+ return ubifs_leb_change(c, lnum, c->sbuf, len, UBI_UNKNOWN);
}
/**
diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c
index 70e8c92..9b2bc56 100644
--- a/fs/ubifs/super.c
+++ b/fs/ubifs/super.c
@@ -914,7 +914,7 @@ static int check_volume_empty(struct ubifs_info *c)
c->empty = 1;
for (lnum = 0; lnum < c->leb_cnt; lnum++) {
- err = ubi_is_mapped(c->ubi, lnum);
+ err = ubifs_is_mapped(c, lnum);
if (unlikely(err < 0))
return err;
if (err == 1) {
--
1.7.2.3
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [PATCH 27/30] UBIFS: stop re-defining UBI operations
2011-06-09 9:04 [PATCH 00/30] UBIFS: latest patches Artem Bityutskiy
` (25 preceding siblings ...)
2011-06-09 9:05 ` [PATCH 26/30] UBIFS: switch to I/O helpers Artem Bityutskiy
@ 2011-06-09 9:05 ` Artem Bityutskiy
2011-06-09 9:05 ` [PATCH 28/30] UBIFS: remove custom list of superblocks Artem Bityutskiy
` (2 subsequent siblings)
29 siblings, 0 replies; 31+ messages in thread
From: Artem Bityutskiy @ 2011-06-09 9:05 UTC (permalink / raw)
To: linux-mtd
From: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
Now when we use UBIFS helpers for all the I/O, we can remove the horrible hack
of re-defining UBI I/O functions.
Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
---
fs/ubifs/debug.c | 2 --
fs/ubifs/debug.h | 7 -------
2 files changed, 0 insertions(+), 9 deletions(-)
diff --git a/fs/ubifs/debug.c b/fs/ubifs/debug.c
index a159cfd..6502657 100644
--- a/fs/ubifs/debug.c
+++ b/fs/ubifs/debug.c
@@ -27,8 +27,6 @@
* various local functions of those subsystems.
*/
-#define UBIFS_DBG_PRESERVE_UBI
-
#include "ubifs.h"
#include <linux/module.h>
#include <linux/debugfs.h>
diff --git a/fs/ubifs/debug.h b/fs/ubifs/debug.h
index b0b005b..b5bc09d 100644
--- a/fs/ubifs/debug.h
+++ b/fs/ubifs/debug.h
@@ -305,13 +305,6 @@ int dbg_check_inode_size(struct ubifs_info *c, const struct inode *inode,
int dbg_check_data_nodes_order(struct ubifs_info *c, struct list_head *head);
int dbg_check_nondata_nodes_order(struct ubifs_info *c, struct list_head *head);
-#ifndef UBIFS_DBG_PRESERVE_UBI
-#define ubi_leb_write dbg_leb_write
-#define ubi_leb_change dbg_leb_change
-#define ubi_leb_unmap dbg_leb_unmap
-#define ubi_leb_map dbg_leb_map
-#endif
-
int dbg_leb_write(struct ubi_volume_desc *desc, int lnum, const void *buf,
int offs, int len, int dtype);
int dbg_leb_change(struct ubi_volume_desc *desc, int lnum, const void *buf,
--
1.7.2.3
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [PATCH 28/30] UBIFS: remove custom list of superblocks
2011-06-09 9:04 [PATCH 00/30] UBIFS: latest patches Artem Bityutskiy
` (26 preceding siblings ...)
2011-06-09 9:05 ` [PATCH 27/30] UBIFS: stop re-defining UBI operations Artem Bityutskiy
@ 2011-06-09 9:05 ` Artem Bityutskiy
2011-06-09 9:05 ` [PATCH 29/30] UBIFS: rename recovery testing variables Artem Bityutskiy
2011-06-09 9:05 ` [PATCH 30/30] UBIFS: improve power cut emulation testing Artem Bityutskiy
29 siblings, 0 replies; 31+ messages in thread
From: Artem Bityutskiy @ 2011-06-09 9:05 UTC (permalink / raw)
To: linux-mtd
From: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
This is a clean-up of the power-cut emulation code - remove the custom list of
superblocks which we maintained to find the superblock by the UBI volume
descriptor. We do not need that crud any longer, because now we can get the
superblock as a function argument.
Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
---
fs/ubifs/debug.c | 105 ++++++++++-------------------------------------------
fs/ubifs/debug.h | 31 ++++++++--------
fs/ubifs/io.c | 8 ++--
3 files changed, 39 insertions(+), 105 deletions(-)
diff --git a/fs/ubifs/debug.c b/fs/ubifs/debug.c
index 6502657..a0e0c95 100644
--- a/fs/ubifs/debug.c
+++ b/fs/ubifs/debug.c
@@ -2539,16 +2539,7 @@ error_dump:
#define chance(n, d) (simple_rand() <= (n) * 32768LL / (d))
-struct failure_mode_info {
- struct list_head list;
- struct ubifs_info *c;
-};
-
-static LIST_HEAD(fmi_list);
-static DEFINE_SPINLOCK(fmi_lock);
-
static unsigned int next;
-
static int simple_rand(void)
{
if (next == 0)
@@ -2557,69 +2548,15 @@ static int simple_rand(void)
return (next >> 16) & 32767;
}
-static void failure_mode_init(struct ubifs_info *c)
-{
- struct failure_mode_info *fmi;
-
- fmi = kmalloc(sizeof(struct failure_mode_info), GFP_NOFS);
- if (!fmi) {
- ubifs_err("Failed to register failure mode - no memory");
- return;
- }
- fmi->c = c;
- spin_lock(&fmi_lock);
- list_add_tail(&fmi->list, &fmi_list);
- spin_unlock(&fmi_lock);
-}
-
-static void failure_mode_exit(struct ubifs_info *c)
-{
- struct failure_mode_info *fmi, *tmp;
-
- spin_lock(&fmi_lock);
- list_for_each_entry_safe(fmi, tmp, &fmi_list, list)
- if (fmi->c == c) {
- list_del(&fmi->list);
- kfree(fmi);
- }
- spin_unlock(&fmi_lock);
-}
-
-static struct ubifs_info *dbg_find_info(struct ubi_volume_desc *desc)
+static int do_fail(struct ubifs_info *c, int lnum, int write)
{
- struct failure_mode_info *fmi;
-
- spin_lock(&fmi_lock);
- list_for_each_entry(fmi, &fmi_list, list)
- if (fmi->c->ubi == desc) {
- struct ubifs_info *c = fmi->c;
-
- spin_unlock(&fmi_lock);
- return c;
- }
- spin_unlock(&fmi_lock);
- return NULL;
-}
-
-static int in_failure_mode(struct ubi_volume_desc *desc)
-{
- struct ubifs_info *c = dbg_find_info(desc);
+ struct ubifs_debug_info *d = c->dbg;
- if (c && dbg_is_tst_rcvry(c))
- return c->dbg->failure_mode;
- return 0;
-}
+ ubifs_assert(dbg_is_tst_rcvry(c));
-static int do_fail(struct ubi_volume_desc *desc, int lnum, int write)
-{
- struct ubifs_info *c = dbg_find_info(desc);
- struct ubifs_debug_info *d;
-
- if (!c || !dbg_is_tst_rcvry(c))
- return 0;
- d = c->dbg;
if (d->failure_mode)
return 1;
+
if (!d->fail_cnt) {
/* First call - decide delay to failure */
if (chance(1, 2)) {
@@ -2716,17 +2653,17 @@ static void cut_data(const void *buf, int len)
p[i] = 0xff;
}
-int dbg_leb_write(struct ubi_volume_desc *desc, int lnum, const void *buf,
+int dbg_leb_write(struct ubifs_info *c, int lnum, const void *buf,
int offs, int len, int dtype)
{
int err, failing;
- if (in_failure_mode(desc))
+ if (c->dbg->failure_mode)
return -EROFS;
- failing = do_fail(desc, lnum, 1);
+ failing = do_fail(c, lnum, 1);
if (failing)
cut_data(buf, len);
- err = ubi_leb_write(desc, lnum, buf, offs, len, dtype);
+ err = ubi_leb_write(c->ubi, lnum, buf, offs, len, dtype);
if (err)
return err;
if (failing)
@@ -2734,45 +2671,45 @@ int dbg_leb_write(struct ubi_volume_desc *desc, int lnum, const void *buf,
return 0;
}
-int dbg_leb_change(struct ubi_volume_desc *desc, int lnum, const void *buf,
+int dbg_leb_change(struct ubifs_info *c, int lnum, const void *buf,
int len, int dtype)
{
int err;
- if (do_fail(desc, lnum, 1))
+ if (do_fail(c, lnum, 1))
return -EROFS;
- err = ubi_leb_change(desc, lnum, buf, len, dtype);
+ err = ubi_leb_change(c->ubi, lnum, buf, len, dtype);
if (err)
return err;
- if (do_fail(desc, lnum, 1))
+ if (do_fail(c, lnum, 1))
return -EROFS;
return 0;
}
-int dbg_leb_unmap(struct ubi_volume_desc *desc, int lnum)
+int dbg_leb_unmap(struct ubifs_info *c, int lnum)
{
int err;
- if (do_fail(desc, lnum, 0))
+ if (do_fail(c, lnum, 0))
return -EROFS;
- err = ubi_leb_unmap(desc, lnum);
+ err = ubi_leb_unmap(c->ubi, lnum);
if (err)
return err;
- if (do_fail(desc, lnum, 0))
+ if (do_fail(c, lnum, 0))
return -EROFS;
return 0;
}
-int dbg_leb_map(struct ubi_volume_desc *desc, int lnum, int dtype)
+int dbg_leb_map(struct ubifs_info *c, int lnum, int dtype)
{
int err;
- if (do_fail(desc, lnum, 0))
+ if (do_fail(c, lnum, 0))
return -EROFS;
- err = ubi_leb_map(desc, lnum, dtype);
+ err = ubi_leb_map(c->ubi, lnum, dtype);
if (err)
return err;
- if (do_fail(desc, lnum, 0))
+ if (do_fail(c, lnum, 0))
return -EROFS;
return 0;
}
@@ -3202,7 +3139,6 @@ int ubifs_debugging_init(struct ubifs_info *c)
if (!c->dbg)
return -ENOMEM;
- failure_mode_init(c);
return 0;
}
@@ -3212,7 +3148,6 @@ int ubifs_debugging_init(struct ubifs_info *c)
*/
void ubifs_debugging_exit(struct ubifs_info *c)
{
- failure_mode_exit(c);
kfree(c->dbg);
}
diff --git a/fs/ubifs/debug.h b/fs/ubifs/debug.h
index b5bc09d..0ab3757 100644
--- a/fs/ubifs/debug.h
+++ b/fs/ubifs/debug.h
@@ -305,12 +305,12 @@ int dbg_check_inode_size(struct ubifs_info *c, const struct inode *inode,
int dbg_check_data_nodes_order(struct ubifs_info *c, struct list_head *head);
int dbg_check_nondata_nodes_order(struct ubifs_info *c, struct list_head *head);
-int dbg_leb_write(struct ubi_volume_desc *desc, int lnum, const void *buf,
- int offs, int len, int dtype);
-int dbg_leb_change(struct ubi_volume_desc *desc, int lnum, const void *buf,
- int len, int dtype);
-int dbg_leb_unmap(struct ubi_volume_desc *desc, int lnum);
-int dbg_leb_map(struct ubi_volume_desc *desc, int lnum, int dtype);
+int dbg_leb_write(struct ubifs_info *c, int lnum, const void *buf, int offs,
+ int len, int dtype);
+int dbg_leb_change(struct ubifs_info *c, int lnum, const void *buf, int len,
+ int dtype);
+int dbg_leb_unmap(struct ubifs_info *c, int lnum);
+int dbg_leb_map(struct ubifs_info *c, int lnum, int dtype);
/* Debugfs-related stuff */
int dbg_debugfs_init(void);
@@ -442,16 +442,15 @@ static inline int
dbg_check_nondata_nodes_order(struct ubifs_info *c,
struct list_head *head) { return 0; }
-static inline int dbg_leb_write(struct ubi_volume_desc *desc,
- int lnum, const void *buf,
- int offset, int len, int dtype) { return 0; }
-static inline int dbg_leb_change(struct ubi_volume_desc *desc,
- int lnum, const void *buf,
- int len, int dtype) { return 0; }
-static inline int dbg_leb_unmap(struct ubi_volume_desc *desc,
- int lnum) { return 0; }
-static inline int dbg_leb_map(struct ubi_volume_desc *desc,
- int lnum, int dtype) { return 0; }
+static inline int dbg_leb_write(struct ubifs_info *c, int lnum,
+ const void *buf, int offset,
+ int len, int dtype) { return 0; }
+static inline int dbg_leb_change(struct ubifs_info *c, int lnum,
+ const void *buf, int len,
+ int dtype) { return 0; }
+static inline int dbg_leb_unmap(struct ubifs_info *c, int lnum) { return 0; }
+static inline int dbg_leb_map(struct ubifs_info *c, int lnum,
+ int dtype) { return 0; }
static inline int dbg_is_chk_gen(const struct ubifs_info *c) { return 0; }
static inline int dbg_is_chk_index(const struct ubifs_info *c) { return 0; }
diff --git a/fs/ubifs/io.c b/fs/ubifs/io.c
index a0c5fb4..9228950 100644
--- a/fs/ubifs/io.c
+++ b/fs/ubifs/io.c
@@ -125,7 +125,7 @@ int ubifs_leb_write(struct ubifs_info *c, int lnum, const void *buf, int offs,
if (!dbg_is_tst_rcvry(c))
err = ubi_leb_write(c->ubi, lnum, buf, offs, len, dtype);
else
- err = dbg_leb_write(c->ubi, lnum, buf, offs, len, dtype);
+ err = dbg_leb_write(c, lnum, buf, offs, len, dtype);
if (err) {
ubifs_err("writing %d bytes to LEB %d:%d failed, error %d",
len, lnum, offs, err);
@@ -146,7 +146,7 @@ int ubifs_leb_change(struct ubifs_info *c, int lnum, const void *buf, int len,
if (!dbg_is_tst_rcvry(c))
err = ubi_leb_change(c->ubi, lnum, buf, len, dtype);
else
- err = dbg_leb_change(c->ubi, lnum, buf, len, dtype);
+ err = dbg_leb_change(c, lnum, buf, len, dtype);
if (err) {
ubifs_err("changing %d bytes in LEB %d failed, error %d",
len, lnum, err);
@@ -166,7 +166,7 @@ int ubifs_leb_unmap(struct ubifs_info *c, int lnum)
if (!dbg_is_tst_rcvry(c))
err = ubi_leb_unmap(c->ubi, lnum);
else
- err = dbg_leb_unmap(c->ubi, lnum);
+ err = dbg_leb_unmap(c, lnum);
if (err) {
ubifs_err("unmap LEB %d failed, error %d", lnum, err);
ubifs_ro_mode(c, err);
@@ -185,7 +185,7 @@ int ubifs_leb_map(struct ubifs_info *c, int lnum, int dtype)
if (!dbg_is_tst_rcvry(c))
err = ubi_leb_map(c->ubi, lnum, dtype);
else
- err = dbg_leb_map(c->ubi, lnum, dtype);
+ err = dbg_leb_map(c, lnum, dtype);
if (err) {
ubifs_err("mapping LEB %d failed, error %d", lnum, err);
ubifs_ro_mode(c, err);
--
1.7.2.3
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [PATCH 29/30] UBIFS: rename recovery testing variables
2011-06-09 9:04 [PATCH 00/30] UBIFS: latest patches Artem Bityutskiy
` (27 preceding siblings ...)
2011-06-09 9:05 ` [PATCH 28/30] UBIFS: remove custom list of superblocks Artem Bityutskiy
@ 2011-06-09 9:05 ` Artem Bityutskiy
2011-06-09 9:05 ` [PATCH 30/30] UBIFS: improve power cut emulation testing Artem Bityutskiy
29 siblings, 0 replies; 31+ messages in thread
From: Artem Bityutskiy @ 2011-06-09 9:05 UTC (permalink / raw)
To: linux-mtd
From: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
Since the recovery testing is effectively about emulating power cuts by UBIFS,
use "power cut" as the base term for all the related variables and name them
correspondingly. This is just a minor clean-up for the sake of readability.
Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
---
fs/ubifs/debug.c | 52 ++++++++++++++++++++++++++++------------------------
fs/ubifs/debug.h | 22 +++++++++++-----------
2 files changed, 39 insertions(+), 35 deletions(-)
diff --git a/fs/ubifs/debug.c b/fs/ubifs/debug.c
index a0e0c95..be45d62 100644
--- a/fs/ubifs/debug.c
+++ b/fs/ubifs/debug.c
@@ -2548,39 +2548,36 @@ static int simple_rand(void)
return (next >> 16) & 32767;
}
-static int do_fail(struct ubifs_info *c, int lnum, int write)
+static int power_cut_emulated(struct ubifs_info *c, int lnum, int write)
{
struct ubifs_debug_info *d = c->dbg;
ubifs_assert(dbg_is_tst_rcvry(c));
- if (d->failure_mode)
- return 1;
-
- if (!d->fail_cnt) {
- /* First call - decide delay to failure */
+ if (!d->pc_cnt) {
+ /* First call - decide delay to the power cut */
if (chance(1, 2)) {
unsigned int delay = 1 << (simple_rand() >> 11);
if (chance(1, 2)) {
- d->fail_delay = 1;
- d->fail_timeout = jiffies +
+ d->pc_delay = 1;
+ d->pc_timeout = jiffies +
msecs_to_jiffies(delay);
ubifs_warn("failing after %ums", delay);
} else {
- d->fail_delay = 2;
- d->fail_cnt_max = delay;
+ d->pc_delay = 2;
+ d->pc_cnt_max = delay;
ubifs_warn("failing after %u calls", delay);
}
}
- d->fail_cnt += 1;
+ d->pc_cnt += 1;
}
/* Determine if failure delay has expired */
- if (d->fail_delay == 1) {
- if (time_before(jiffies, d->fail_timeout))
+ if (d->pc_delay == 1) {
+ if (time_before(jiffies, d->pc_timeout))
return 0;
- } else if (d->fail_delay == 2)
- if (d->fail_cnt++ < d->fail_cnt_max)
+ } else if (d->pc_delay == 2)
+ if (d->pc_cnt++ < d->pc_cnt_max)
return 0;
if (lnum == UBIFS_SB_LNUM) {
if (write) {
@@ -2638,7 +2635,7 @@ static int do_fail(struct ubifs_info *c, int lnum, int write)
ubifs_warn("failing in bud LEB %d commit not running", lnum);
}
- d->failure_mode = 1;
+ d->pc_happened = 1;
dump_stack();
return 1;
}
@@ -2658,9 +2655,10 @@ int dbg_leb_write(struct ubifs_info *c, int lnum, const void *buf,
{
int err, failing;
- if (c->dbg->failure_mode)
+ if (c->dbg->pc_happened)
return -EROFS;
- failing = do_fail(c, lnum, 1);
+
+ failing = power_cut_emulated(c, lnum, 1);
if (failing)
cut_data(buf, len);
err = ubi_leb_write(c->ubi, lnum, buf, offs, len, dtype);
@@ -2676,12 +2674,14 @@ int dbg_leb_change(struct ubifs_info *c, int lnum, const void *buf,
{
int err;
- if (do_fail(c, lnum, 1))
+ if (c->dbg->pc_happened)
+ return -EROFS;
+ if (power_cut_emulated(c, lnum, 1))
return -EROFS;
err = ubi_leb_change(c->ubi, lnum, buf, len, dtype);
if (err)
return err;
- if (do_fail(c, lnum, 1))
+ if (power_cut_emulated(c, lnum, 1))
return -EROFS;
return 0;
}
@@ -2690,12 +2690,14 @@ int dbg_leb_unmap(struct ubifs_info *c, int lnum)
{
int err;
- if (do_fail(c, lnum, 0))
+ if (c->dbg->pc_happened)
+ return -EROFS;
+ if (power_cut_emulated(c, lnum, 0))
return -EROFS;
err = ubi_leb_unmap(c->ubi, lnum);
if (err)
return err;
- if (do_fail(c, lnum, 0))
+ if (power_cut_emulated(c, lnum, 0))
return -EROFS;
return 0;
}
@@ -2704,12 +2706,14 @@ int dbg_leb_map(struct ubifs_info *c, int lnum, int dtype)
{
int err;
- if (do_fail(c, lnum, 0))
+ if (c->dbg->pc_happened)
+ return -EROFS;
+ if (power_cut_emulated(c, lnum, 0))
return -EROFS;
err = ubi_leb_map(c->ubi, lnum, dtype);
if (err)
return err;
- if (do_fail(c, lnum, 0))
+ if (power_cut_emulated(c, lnum, 0))
return -EROFS;
return 0;
}
diff --git a/fs/ubifs/debug.h b/fs/ubifs/debug.h
index 0ab3757..45174b5 100644
--- a/fs/ubifs/debug.h
+++ b/fs/ubifs/debug.h
@@ -44,11 +44,11 @@ typedef int (*dbg_znode_callback)(struct ubifs_info *c,
* @old_zroot_level: old index root level - used by 'dbg_check_old_index()'
* @old_zroot_sqnum: old index root sqnum - used by 'dbg_check_old_index()'
*
- * @failure_mode: failure mode for recovery testing
- * @fail_delay: 0=>don't delay, 1=>delay a time, 2=>delay a number of calls
- * @fail_timeout: time in jiffies when delay of failure mode expires
- * @fail_cnt: current number of calls to failure mode I/O functions
- * @fail_cnt_max: number of calls by which to delay failure mode
+ * @pc_happened: non-zero if an emulated power cut happened
+ * @pc_delay: 0=>don't delay, 1=>delay a time, 2=>delay a number of calls
+ * @pc_timeout: time in jiffies when delay of failure mode expires
+ * @pc_cnt: current number of calls to failure mode I/O functions
+ * @pc_cnt_max: number of calls by which to delay failure mode
*
* @chk_lpt_sz: used by LPT tree size checker
* @chk_lpt_sz2: used by LPT tree size checker
@@ -87,11 +87,11 @@ struct ubifs_debug_info {
int old_zroot_level;
unsigned long long old_zroot_sqnum;
- int failure_mode;
- int fail_delay;
- unsigned long fail_timeout;
- unsigned int fail_cnt;
- unsigned int fail_cnt_max;
+ int pc_happened;
+ int pc_delay;
+ unsigned long pc_timeout;
+ unsigned int pc_cnt;
+ unsigned int pc_cnt_max;
long long chk_lpt_sz;
long long chk_lpt_sz2;
@@ -246,7 +246,7 @@ static inline int dbg_is_tst_rcvry(const struct ubifs_info *c)
}
static inline int dbg_is_power_cut(const struct ubifs_info *c)
{
- return !!c->dbg->failure_mode;
+ return !!c->dbg->pc_happened;
}
int ubifs_debugging_init(struct ubifs_info *c);
--
1.7.2.3
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [PATCH 30/30] UBIFS: improve power cut emulation testing
2011-06-09 9:04 [PATCH 00/30] UBIFS: latest patches Artem Bityutskiy
` (28 preceding siblings ...)
2011-06-09 9:05 ` [PATCH 29/30] UBIFS: rename recovery testing variables Artem Bityutskiy
@ 2011-06-09 9:05 ` Artem Bityutskiy
29 siblings, 0 replies; 31+ messages in thread
From: Artem Bityutskiy @ 2011-06-09 9:05 UTC (permalink / raw)
To: linux-mtd
From: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
This patch cleans-up and improves the power cut testing:
1. Kill custom 'simple_random()' function and use 'random32()' instead.
2. Make timeout larger
3. When cutting the buffer - fill the end with random data sometimes, not
only with 0xFFs.
4. Some times cut in the middle of the buffer, not always at the end.
Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
---
fs/ubifs/debug.c | 91 +++++++++++++++++++++++++++++------------------------
1 files changed, 50 insertions(+), 41 deletions(-)
diff --git a/fs/ubifs/debug.c b/fs/ubifs/debug.c
index be45d62..48b6369 100644
--- a/fs/ubifs/debug.c
+++ b/fs/ubifs/debug.c
@@ -27,11 +27,12 @@
* various local functions of those subsystems.
*/
-#include "ubifs.h"
#include <linux/module.h>
#include <linux/debugfs.h>
#include <linux/math64.h>
#include <linux/uaccess.h>
+#include <linux/random.h>
+#include "ubifs.h"
#ifdef CONFIG_UBIFS_FS_DEBUG
@@ -2535,17 +2536,10 @@ error_dump:
return 0;
}
-/* Failure mode for recovery testing */
-
-#define chance(n, d) (simple_rand() <= (n) * 32768LL / (d))
-
-static unsigned int next;
-static int simple_rand(void)
+static inline int chance(unsigned int n, unsigned int out_of)
{
- if (next == 0)
- next = current->pid;
- next = next * 1103515245 + 12345;
- return (next >> 16) & 32767;
+ return !!((random32() % out_of) + 1 <= n);
+
}
static int power_cut_emulated(struct ubifs_info *c, int lnum, int write)
@@ -2557,33 +2551,37 @@ static int power_cut_emulated(struct ubifs_info *c, int lnum, int write)
if (!d->pc_cnt) {
/* First call - decide delay to the power cut */
if (chance(1, 2)) {
- unsigned int delay = 1 << (simple_rand() >> 11);
+ unsigned long delay;
if (chance(1, 2)) {
d->pc_delay = 1;
- d->pc_timeout = jiffies +
- msecs_to_jiffies(delay);
- ubifs_warn("failing after %ums", delay);
+ /* Fail withing 1 minute */
+ delay = random32() % 60000;
+ d->pc_timeout = jiffies;
+ d->pc_timeout += msecs_to_jiffies(delay);
+ ubifs_warn("failing after %lums", delay);
} else {
d->pc_delay = 2;
+ delay = random32() % 10000;
+ /* Fail within 10000 operations */
d->pc_cnt_max = delay;
- ubifs_warn("failing after %u calls", delay);
+ ubifs_warn("failing after %lu calls", delay);
}
}
+
d->pc_cnt += 1;
}
+
/* Determine if failure delay has expired */
- if (d->pc_delay == 1) {
- if (time_before(jiffies, d->pc_timeout))
+ if (d->pc_delay == 1 && time_before(jiffies, d->pc_timeout))
return 0;
- } else if (d->pc_delay == 2)
- if (d->pc_cnt++ < d->pc_cnt_max)
+ if (d->pc_delay == 2 && d->pc_cnt++ < d->pc_cnt_max)
return 0;
+
if (lnum == UBIFS_SB_LNUM) {
- if (write) {
- if (chance(1, 2))
- return 0;
- } else if (chance(19, 20))
+ if (write && chance(1, 2))
+ return 0;
+ if (chance(19, 20))
return 0;
ubifs_warn("failing in super block LEB %d", lnum);
} else if (lnum == UBIFS_MST_LNUM || lnum == UBIFS_MST_LNUM + 1) {
@@ -2591,24 +2589,21 @@ static int power_cut_emulated(struct ubifs_info *c, int lnum, int write)
return 0;
ubifs_warn("failing in master LEB %d", lnum);
} else if (lnum >= UBIFS_LOG_LNUM && lnum <= c->log_last) {
- if (write) {
- if (chance(99, 100))
- return 0;
- } else if (chance(399, 400))
+ if (write && chance(99, 100))
+ return 0;
+ if (chance(399, 400))
return 0;
ubifs_warn("failing in log LEB %d", lnum);
} else if (lnum >= c->lpt_first && lnum <= c->lpt_last) {
- if (write) {
- if (chance(7, 8))
- return 0;
- } else if (chance(19, 20))
+ if (write && chance(7, 8))
+ return 0;
+ if (chance(19, 20))
return 0;
ubifs_warn("failing in LPT LEB %d", lnum);
} else if (lnum >= c->orph_first && lnum <= c->orph_last) {
- if (write) {
- if (chance(1, 2))
- return 0;
- } else if (chance(9, 10))
+ if (write && chance(1, 2))
+ return 0;
+ if (chance(9, 10))
return 0;
ubifs_warn("failing in orphan LEB %d", lnum);
} else if (lnum == c->ihead_lnum) {
@@ -2636,18 +2631,32 @@ static int power_cut_emulated(struct ubifs_info *c, int lnum, int write)
}
d->pc_happened = 1;
+ ubifs_warn("========== Power cut emulated ==========");
dump_stack();
return 1;
}
-static void cut_data(const void *buf, int len)
+static void cut_data(const void *buf, unsigned int len)
{
- int flen, i;
+ unsigned int from, to, i, ffs = chance(1, 2);
unsigned char *p = (void *)buf;
- flen = (len * (long long)simple_rand()) >> 15;
- for (i = flen; i < len; i++)
- p[i] = 0xff;
+ from = random32() % (len + 1);
+ if (chance(1, 2))
+ to = random32() % (len - from + 1);
+ else
+ to = len;
+
+ if (from < to)
+ ubifs_warn("filled bytes %u-%u with %s", from, to - 1,
+ ffs ? "0xFFs" : "random data");
+
+ if (ffs)
+ for (i = from; i < to; i++)
+ p[i] = 0xFF;
+ else
+ for (i = from; i < to; i++)
+ p[i] = random32() % 0x100;
}
int dbg_leb_write(struct ubifs_info *c, int lnum, const void *buf,
--
1.7.2.3
^ permalink raw reply related [flat|nested] 31+ messages in thread
end of thread, other threads:[~2011-06-09 9:01 UTC | newest]
Thread overview: 31+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-06-09 9:04 [PATCH 00/30] UBIFS: latest patches Artem Bityutskiy
2011-06-09 9:04 ` [PATCH 01/30] UBIFS: return EROFS in case of broken commit Artem Bityutskiy
2011-06-09 9:04 ` [PATCH 02/30] UBIFS: lessen the size of debugging info data structure Artem Bityutskiy
2011-06-09 9:04 ` [PATCH 03/30] UBIFS: dump stack when pnode or nnode reading fails Artem Bityutskiy
2011-06-09 9:04 ` [PATCH 04/30] UBIFS: improve inode dumping function Artem Bityutskiy
2011-06-09 9:04 ` [PATCH 05/30] UBIFS: rename dbg_check_dir_size function Artem Bityutskiy
2011-06-09 9:04 ` [PATCH 06/30] UBIFS: minor cleanup: use S_ISREG helper Artem Bityutskiy
2011-06-09 9:04 ` [PATCH 07/30] UBIFS: remove unnecessary brackets Artem Bityutskiy
2011-06-09 9:04 ` [PATCH 08/30] UBIFS: remove dead code Artem Bityutskiy
2011-06-09 9:04 ` [PATCH 09/30] UBIFS: harmonize znode flag helpers Artem Bityutskiy
2011-06-09 9:04 ` [PATCH 10/30] UBIFS: use correct flags in lprops Artem Bityutskiy
2011-06-09 9:04 ` [PATCH 11/30] UBIFS: add few commentaries about TNC Artem Bityutskiy
2011-06-09 9:04 ` [PATCH 12/30] UBIFS: amend debugging name check function prototype Artem Bityutskiy
2011-06-09 9:04 ` [PATCH 13/30] UBIFS: amend debugging inode size " Artem Bityutskiy
2011-06-09 9:04 ` [PATCH 14/30] UBIFS: introduce helper functions for debugging checks and tests Artem Bityutskiy
2011-06-09 9:04 ` [PATCH 15/30] UBIFS: lessen amount of debugging check types Artem Bityutskiy
2011-06-09 9:04 ` [PATCH 16/30] UBIFS: switch self-check knobs to debugfs Artem Bityutskiy
2011-06-09 9:04 ` [PATCH 17/30] UBIFS: be more informative in failure mode Artem Bityutskiy
2011-06-09 9:04 ` [PATCH 18/30] UBIFS: re-arrange debugging code a bit Artem Bityutskiy
2011-06-09 9:04 ` [PATCH 19/30] UBIFS: introduce debugfs helpers Artem Bityutskiy
2011-06-09 9:05 ` [PATCH 20/30] UBIFS: add global debugfs knobs Artem Bityutskiy
2011-06-09 9:05 ` [PATCH 21/30] UBIFS: remove unused and unneeded debugging function Artem Bityutskiy
2011-06-09 9:05 ` [PATCH 22/30] UBIFS: always print stacktrace when switching to R/O mode Artem Bityutskiy
2011-06-09 9:05 ` [PATCH 23/30] UBIFS: introduce more I/O helpers Artem Bityutskiy
2011-06-09 9:05 ` [PATCH 24/30] UBIFS: switch to ubifs_leb_read Artem Bityutskiy
2011-06-09 9:05 ` [PATCH 25/30] UBIFS: switch to ubifs_leb_write Artem Bityutskiy
2011-06-09 9:05 ` [PATCH 26/30] UBIFS: switch to I/O helpers Artem Bityutskiy
2011-06-09 9:05 ` [PATCH 27/30] UBIFS: stop re-defining UBI operations Artem Bityutskiy
2011-06-09 9:05 ` [PATCH 28/30] UBIFS: remove custom list of superblocks Artem Bityutskiy
2011-06-09 9:05 ` [PATCH 29/30] UBIFS: rename recovery testing variables Artem Bityutskiy
2011-06-09 9:05 ` [PATCH 30/30] UBIFS: improve power cut emulation testing Artem Bityutskiy
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).