diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-07-23 15:50:52 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-07-23 15:50:52 -0700 |
commit | 93912fe69d67597ee4c0b451d24539ead550bdc3 (patch) | |
tree | d12729aa17d43d0e8010d7ff3d6a0ef7ad70f304 /fs/ubifs | |
parent | 0ec4f431eb56d633da3a55da67d5c4b88886ccc7 (diff) | |
parent | 7074e5eb233343e4bad8c0a3f9e73167cf85a159 (diff) | |
download | lwn-93912fe69d67597ee4c0b451d24539ead550bdc3.tar.gz lwn-93912fe69d67597ee4c0b451d24539ead550bdc3.zip |
Merge tag 'upstream-3.6-rc1' of git://git.infradead.org/linux-ubifs
Pull UBIFS updates from Artem Bityutskiy:
- Added another debugfs knob for forcing UBIFS R/O mode without
flushing caches or finishing commit or any other I/O operation. I've
originally added this knob in order to reproduce the free space fixup
bug (see commit c6727932cfdb: "UBIFS: fix a bug in empty space
fix-up") on nandsim.
Without this knob I would have to do real power-cuts, which would
make debugging much harder. Then I've decided to keep this knob
because it is also useful for UBIFS power-cut recovery end
error-paths testing.
- Well-spotted fix from Julia. This bug did not cause real troubles
for UBIFS, but nevertheless it could cause issues for someone trying
to modify the orphans handling code. Kudos to coccinelle!
- Minor cleanups.
* tag 'upstream-3.6-rc1' of git://git.infradead.org/linux-ubifs:
UBIFS: remove invalid reference to list iterator variable
UBIFS: simplify reply code a bit
UBIFS: add debugfs knob to switch to R/O mode
UBIFS: fix compilation warning
Diffstat (limited to 'fs/ubifs')
-rw-r--r-- | fs/ubifs/debug.c | 11 | ||||
-rw-r--r-- | fs/ubifs/debug.h | 5 | ||||
-rw-r--r-- | fs/ubifs/dir.c | 2 | ||||
-rw-r--r-- | fs/ubifs/orphan.c | 4 | ||||
-rw-r--r-- | fs/ubifs/replay.c | 20 |
5 files changed, 25 insertions, 17 deletions
diff --git a/fs/ubifs/debug.c b/fs/ubifs/debug.c index 92df3b081539..bb3167257aab 100644 --- a/fs/ubifs/debug.c +++ b/fs/ubifs/debug.c @@ -2802,6 +2802,8 @@ static ssize_t dfs_file_read(struct file *file, char __user *u, size_t count, val = d->chk_fs; else if (dent == d->dfs_tst_rcvry) val = d->tst_rcvry; + else if (dent == d->dfs_ro_error) + val = c->ro_error; else return -EINVAL; @@ -2885,6 +2887,8 @@ static ssize_t dfs_file_write(struct file *file, const char __user *u, d->chk_fs = val; else if (dent == d->dfs_tst_rcvry) d->tst_rcvry = val; + else if (dent == d->dfs_ro_error) + c->ro_error = !!val; else return -EINVAL; @@ -2996,6 +3000,13 @@ int dbg_debugfs_init_fs(struct ubifs_info *c) goto out_remove; d->dfs_tst_rcvry = dent; + fname = "ro_error"; + 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_ro_error = dent; + return 0; out_remove: diff --git a/fs/ubifs/debug.h b/fs/ubifs/debug.h index 486a8e024fb6..8b8cc4e945f4 100644 --- a/fs/ubifs/debug.h +++ b/fs/ubifs/debug.h @@ -79,6 +79,10 @@ typedef int (*dbg_znode_callback)(struct ubifs_info *c, * @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 + * @dfs_ro_error: debugfs knob to switch UBIFS to R/O mode (different to + * re-mounting to R/O mode because it does not flush any buffers + * and UBIFS just starts returning -EROFS on all write + * operations) */ struct ubifs_debug_info { struct ubifs_zbranch old_zroot; @@ -122,6 +126,7 @@ struct ubifs_debug_info { struct dentry *dfs_chk_lprops; struct dentry *dfs_chk_fs; struct dentry *dfs_tst_rcvry; + struct dentry *dfs_ro_error; }; /** diff --git a/fs/ubifs/dir.c b/fs/ubifs/dir.c index b1cca89aeb68..c95681cf1b71 100644 --- a/fs/ubifs/dir.c +++ b/fs/ubifs/dir.c @@ -969,7 +969,7 @@ static int ubifs_rename(struct inode *old_dir, struct dentry *old_dentry, struct ubifs_budget_req ino_req = { .dirtied_ino = 1, .dirtied_ino_d = ALIGN(old_inode_ui->data_len, 8) }; struct timespec time; - unsigned int saved_nlink; + unsigned int uninitialized_var(saved_nlink); /* * Budget request settings: deletion direntry, new direntry, removing diff --git a/fs/ubifs/orphan.c b/fs/ubifs/orphan.c index b02734db187c..cebf17ea0458 100644 --- a/fs/ubifs/orphan.c +++ b/fs/ubifs/orphan.c @@ -176,7 +176,7 @@ int ubifs_orphan_start_commit(struct ubifs_info *c) *last = orphan; last = &orphan->cnext; } - *last = orphan->cnext; + *last = NULL; c->cmt_orphans = c->new_orphans; c->new_orphans = 0; dbg_cmt("%d orphans to commit", c->cmt_orphans); @@ -382,7 +382,7 @@ static int consolidate(struct ubifs_info *c) last = &orphan->cnext; cnt += 1; } - *last = orphan->cnext; + *last = NULL; ubifs_assert(cnt == c->tot_orphans - c->new_orphans); c->cmt_orphans = cnt; c->ohead_lnum = c->orph_first; diff --git a/fs/ubifs/replay.c b/fs/ubifs/replay.c index 3a2da7e476e5..eba46d4a7619 100644 --- a/fs/ubifs/replay.c +++ b/fs/ubifs/replay.c @@ -1007,7 +1007,7 @@ out: */ int ubifs_replay_journal(struct ubifs_info *c) { - int err, i, lnum, offs, free; + int err, lnum, free; BUILD_BUG_ON(UBIFS_TRUN_KEY > 5); @@ -1025,25 +1025,17 @@ int ubifs_replay_journal(struct ubifs_info *c) dbg_mnt("start replaying the journal"); c->replaying = 1; lnum = c->ltail_lnum = c->lhead_lnum; - offs = c->lhead_offs; - for (i = 0; i < c->log_lebs; i++, lnum++) { - if (lnum >= UBIFS_LOG_LNUM + c->log_lebs) { - /* - * The log is logically circular, we reached the last - * LEB, switch to the first one. - */ - lnum = UBIFS_LOG_LNUM; - offs = 0; - } - err = replay_log_leb(c, lnum, offs, c->sbuf); + lnum = UBIFS_LOG_LNUM; + do { + err = replay_log_leb(c, lnum, 0, c->sbuf); if (err == 1) /* We hit the end of the log */ break; if (err) goto out; - offs = 0; - } + lnum = ubifs_next_log_lnum(c, lnum); + } while (lnum != UBIFS_LOG_LNUM); err = replay_buds(c); if (err) |