summaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-10-14 08:38:54 +0200
committerLinus Torvalds <torvalds@linux-foundation.org>2014-10-14 08:38:54 +0200
commitb11445f830df0ec9271f39bff19ecc6f8db58eb8 (patch)
tree31b972607d563c099406235f9abcac687d1b583e /fs
parent0ef3a56b1c466629cd0bf482b09c7b0e5a085bb5 (diff)
parent91401a34038e614076dbfb5c4969a052e72fb296 (diff)
downloadlinux-b11445f830df0ec9271f39bff19ecc6f8db58eb8.tar.bz2
Merge tag 'upstream-3.18-rc1-v2' of git://git.infradead.org/linux-ubifs
Pull UBI/UBIFS fixes from Artem Bityutskiy: - fix for a theoretical race condition which could lead to a situation when UBIFS is unable to mount a file-system (Hujianyang) - a few fixes for the ubiblock sybsystem, error path fixes - the ubiblock subsystem has had the volume size change handling improved - a few fixes and nicifications in the fastmap subsystem * tag 'upstream-3.18-rc1-v2' of git://git.infradead.org/linux-ubifs: UBI: Fastmap: Calc fastmap size correctly UBIFS: Fix trivial typo in power_cut_emulated() UBI: Fix trivial typo in __schedule_ubi_work UBI: wl: Rename cancel flag to shutdown UBI: ubi_eba_read_leb: Remove in vain variable assignment UBIFS: Align the dump messages of SB_NODE UBI: Fix livelock in produce_free_peb() UBI: return on error in rename_volumes() UBI: Improve comment on work_sem UBIFS: Remove bogus assert UBI: Dispatch update notification if the volume is updated UBI: block: Add support for the UBI_VOLUME_UPDATED notification UBI: block: Fix block device size setting UBI: block: fix dereference on uninitialized dev UBI: add missing kmem_cache_free() in process_pool_aeb error path UBIFS: fix free log space calculation UBIFS: fix a race condition
Diffstat (limited to 'fs')
-rw-r--r--fs/ubifs/commit.c8
-rw-r--r--fs/ubifs/debug.c6
-rw-r--r--fs/ubifs/journal.c7
-rw-r--r--fs/ubifs/log.c19
4 files changed, 23 insertions, 17 deletions
diff --git a/fs/ubifs/commit.c b/fs/ubifs/commit.c
index aa13ad053b14..26b69b2d4a45 100644
--- a/fs/ubifs/commit.c
+++ b/fs/ubifs/commit.c
@@ -166,10 +166,6 @@ static int do_commit(struct ubifs_info *c)
err = ubifs_orphan_end_commit(c);
if (err)
goto out;
- old_ltail_lnum = c->ltail_lnum;
- err = ubifs_log_end_commit(c, new_ltail_lnum);
- if (err)
- goto out;
err = dbg_check_old_index(c, &zroot);
if (err)
goto out;
@@ -202,7 +198,9 @@ static int do_commit(struct ubifs_info *c)
c->mst_node->flags |= cpu_to_le32(UBIFS_MST_NO_ORPHS);
else
c->mst_node->flags &= ~cpu_to_le32(UBIFS_MST_NO_ORPHS);
- err = ubifs_write_master(c);
+
+ old_ltail_lnum = c->ltail_lnum;
+ err = ubifs_log_end_commit(c, new_ltail_lnum);
if (err)
goto out;
diff --git a/fs/ubifs/debug.c b/fs/ubifs/debug.c
index 177b0152fef4..7ed13e1e216a 100644
--- a/fs/ubifs/debug.c
+++ b/fs/ubifs/debug.c
@@ -334,9 +334,9 @@ void ubifs_dump_node(const struct ubifs_info *c, const void *node)
pr_err("\tkey_fmt %d (%s)\n",
(int)sup->key_fmt, get_key_fmt(sup->key_fmt));
pr_err("\tflags %#x\n", sup_flags);
- pr_err("\t big_lpt %u\n",
+ pr_err("\tbig_lpt %u\n",
!!(sup_flags & UBIFS_FLG_BIGLPT));
- pr_err("\t space_fixup %u\n",
+ pr_err("\tspace_fixup %u\n",
!!(sup_flags & UBIFS_FLG_SPACE_FIXUP));
pr_err("\tmin_io_size %u\n", le32_to_cpu(sup->min_io_size));
pr_err("\tleb_size %u\n", le32_to_cpu(sup->leb_size));
@@ -2462,7 +2462,7 @@ static int power_cut_emulated(struct ubifs_info *c, int lnum, int write)
if (chance(1, 2)) {
d->pc_delay = 1;
- /* Fail withing 1 minute */
+ /* Fail within 1 minute */
delay = prandom_u32() % 60000;
d->pc_timeout = jiffies;
d->pc_timeout += msecs_to_jiffies(delay);
diff --git a/fs/ubifs/journal.c b/fs/ubifs/journal.c
index 0e045e75abd8..fb166e204441 100644
--- a/fs/ubifs/journal.c
+++ b/fs/ubifs/journal.c
@@ -546,15 +546,14 @@ int ubifs_jnl_update(struct ubifs_info *c, const struct inode *dir,
int aligned_dlen, aligned_ilen, sync = IS_DIRSYNC(dir);
int last_reference = !!(deletion && inode->i_nlink == 0);
struct ubifs_inode *ui = ubifs_inode(inode);
- struct ubifs_inode *dir_ui = ubifs_inode(dir);
+ struct ubifs_inode *host_ui = ubifs_inode(dir);
struct ubifs_dent_node *dent;
struct ubifs_ino_node *ino;
union ubifs_key dent_key, ino_key;
dbg_jnl("ino %lu, dent '%.*s', data len %d in dir ino %lu",
inode->i_ino, nm->len, nm->name, ui->data_len, dir->i_ino);
- ubifs_assert(dir_ui->data_len == 0);
- ubifs_assert(mutex_is_locked(&dir_ui->ui_mutex));
+ ubifs_assert(mutex_is_locked(&host_ui->ui_mutex));
dlen = UBIFS_DENT_NODE_SZ + nm->len + 1;
ilen = UBIFS_INO_NODE_SZ;
@@ -658,7 +657,7 @@ int ubifs_jnl_update(struct ubifs_info *c, const struct inode *dir,
ui->synced_i_size = ui->ui_size;
spin_unlock(&ui->ui_lock);
mark_inode_clean(c, ui);
- mark_inode_clean(c, dir_ui);
+ mark_inode_clean(c, host_ui);
return 0;
out_finish:
diff --git a/fs/ubifs/log.c b/fs/ubifs/log.c
index a47ddfc9be6b..c14628fbeee2 100644
--- a/fs/ubifs/log.c
+++ b/fs/ubifs/log.c
@@ -106,10 +106,14 @@ static inline long long empty_log_bytes(const struct ubifs_info *c)
h = (long long)c->lhead_lnum * c->leb_size + c->lhead_offs;
t = (long long)c->ltail_lnum * c->leb_size;
- if (h >= t)
+ if (h > t)
return c->log_bytes - h + t;
- else
+ else if (h != t)
return t - h;
+ else if (c->lhead_lnum != c->ltail_lnum)
+ return 0;
+ else
+ return c->log_bytes;
}
/**
@@ -447,9 +451,9 @@ out:
* @ltail_lnum: new log tail LEB number
*
* This function is called on when the commit operation was finished. It
- * moves log tail to new position and unmaps LEBs which contain obsolete data.
- * Returns zero in case of success and a negative error code in case of
- * failure.
+ * moves log tail to new position and updates the master node so that it stores
+ * the new log tail LEB number. Returns zero in case of success and a negative
+ * error code in case of failure.
*/
int ubifs_log_end_commit(struct ubifs_info *c, int ltail_lnum)
{
@@ -477,7 +481,12 @@ int ubifs_log_end_commit(struct ubifs_info *c, int ltail_lnum)
spin_unlock(&c->buds_lock);
err = dbg_check_bud_bytes(c);
+ if (err)
+ goto out;
+ err = ubifs_write_master(c);
+
+out:
mutex_unlock(&c->log_mutex);
return err;
}