summaryrefslogtreecommitdiffstats
path: root/fs/jffs2
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2015-06-23 17:38:39 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2015-06-23 17:38:39 -0700
commit54245ed870c8cf9ff87fdf78955ffbc93b261e9f (patch)
treed1cbb9294861c4f55d8d5fd6eac7b96f5283f538 /fs/jffs2
parent84e9c87e6ffc519fdf91949482a65672a7314c9a (diff)
parent0eb8618bd07533f423fed47399a0d6387bfe7cac (diff)
downloadlinux-54245ed870c8cf9ff87fdf78955ffbc93b261e9f.tar.bz2
Merge tag 'for-linus-20150623' of git://git.infradead.org/linux-mtd
Pull MTD updates from Brian Norris: "JFFS2: - fix a theoretical unbalanced locking issue; the lock handling was a bit unclean, but AFAICT, it didn't actually lead to real deadlocks NAND: - brcmnand driver: new driver supporting NAND controller found originally on Broadcom STB SoCs (BCM7xxx), but now also found on BCM63xxx, iProc (e.g., Cygnus, BCM5301x), BCM3xxx, and more - begin factoring out BBT code so it can be shared between traditional (parallel) NAND drivers and upcoming SPI NAND drivers (WIP) - add common DT-based init support, so nand_base can pick up some flash properties automatically, using established common NAND DT properties - mxc_nand: support 8-bit ECC - pxa3xx_nand: * fix build for ARM64 * use a jiffies-based timeout SPI NOR: - add a few new IDs - clear out some unnecessary entries - make sure SECT_4K flags are correct for all (?) entries Core: - fix mtd->usecount race conditions (BUG_ON()) - switch to modern PM ops Other: - CFI: save code space by de-inlining large functions - clean up some partition parser selection code across several drivers - various miscellaneous changes, mostly minor" * tag 'for-linus-20150623' of git://git.infradead.org/linux-mtd: (57 commits) mtd: docg3: Fix kasprintf() usage mtd: docg3: Don't leak docg3->bbt in error path mtd: nandsim: Fix kasprintf() usage mtd: cs553x_nand: Fix kasprintf() usage mtd: r852: Fix device_create_file() usage mtd: brcmnand: drop unnecessary initialization mtd: propagate error codes from add_mtd_device() mtd: diskonchip: remove two-phase partitioning / registration mtd: dc21285: use raw spinlock functions for nw_gpio_lock mtd: chips: fixup dependencies, to prevent build error mtd: cfi_cmdset_0002: Initialize datum before calling map_word_load_partial mtd: cfi: deinline large functions mtd: lantiq-flash: use default partition parsers mtd: plat_nand: use default partition probe mtd: nand: correct indentation within conditional mtd: remove incorrect file name mtd: blktrans: use better error code for unimplemented ioctl() mtd: maps: Spelling s/reseved/reserved/ mtd: blktrans: change blktrans_getgeo return value mtd: mxc_nand: generate nand_ecclayout for 8 bit ECC ...
Diffstat (limited to 'fs/jffs2')
-rw-r--r--fs/jffs2/fs.c7
-rw-r--r--fs/jffs2/readinode.c27
2 files changed, 6 insertions, 28 deletions
diff --git a/fs/jffs2/fs.c b/fs/jffs2/fs.c
index 60d86e8fba6e..2caf1682036d 100644
--- a/fs/jffs2/fs.c
+++ b/fs/jffs2/fs.c
@@ -272,12 +272,9 @@ struct inode *jffs2_iget(struct super_block *sb, unsigned long ino)
mutex_lock(&f->sem);
ret = jffs2_do_read_inode(c, f, inode->i_ino, &latest_node);
+ if (ret)
+ goto error;
- if (ret) {
- mutex_unlock(&f->sem);
- iget_failed(inode);
- return ERR_PTR(ret);
- }
inode->i_mode = jemode_to_cpu(latest_node.mode);
i_uid_write(inode, je16_to_cpu(latest_node.uid));
i_gid_write(inode, je16_to_cpu(latest_node.gid));
diff --git a/fs/jffs2/readinode.c b/fs/jffs2/readinode.c
index dddbde4f56f4..28e0aab42bc3 100644
--- a/fs/jffs2/readinode.c
+++ b/fs/jffs2/readinode.c
@@ -1203,17 +1203,13 @@ static int jffs2_do_read_inode_internal(struct jffs2_sb_info *c,
JFFS2_ERROR("failed to read from flash: error %d, %zd of %zd bytes read\n",
ret, retlen, sizeof(*latest_node));
/* FIXME: If this fails, there seems to be a memory leak. Find it. */
- mutex_unlock(&f->sem);
- jffs2_do_clear_inode(c, f);
- return ret?ret:-EIO;
+ return ret ? ret : -EIO;
}
crc = crc32(0, latest_node, sizeof(*latest_node)-8);
if (crc != je32_to_cpu(latest_node->node_crc)) {
JFFS2_ERROR("CRC failed for read_inode of inode %u at physical location 0x%x\n",
f->inocache->ino, ref_offset(rii.latest_ref));
- mutex_unlock(&f->sem);
- jffs2_do_clear_inode(c, f);
return -EIO;
}
@@ -1250,16 +1246,11 @@ static int jffs2_do_read_inode_internal(struct jffs2_sb_info *c,
* keep in RAM to facilitate quick follow symlink
* operation. */
uint32_t csize = je32_to_cpu(latest_node->csize);
- if (csize > JFFS2_MAX_NAME_LEN) {
- mutex_unlock(&f->sem);
- jffs2_do_clear_inode(c, f);
+ if (csize > JFFS2_MAX_NAME_LEN)
return -ENAMETOOLONG;
- }
f->target = kmalloc(csize + 1, GFP_KERNEL);
if (!f->target) {
JFFS2_ERROR("can't allocate %u bytes of memory for the symlink target path cache\n", csize);
- mutex_unlock(&f->sem);
- jffs2_do_clear_inode(c, f);
return -ENOMEM;
}
@@ -1271,8 +1262,6 @@ static int jffs2_do_read_inode_internal(struct jffs2_sb_info *c,
ret = -EIO;
kfree(f->target);
f->target = NULL;
- mutex_unlock(&f->sem);
- jffs2_do_clear_inode(c, f);
return ret;
}
@@ -1289,15 +1278,11 @@ static int jffs2_do_read_inode_internal(struct jffs2_sb_info *c,
if (f->metadata) {
JFFS2_ERROR("Argh. Special inode #%u with mode 0%o had metadata node\n",
f->inocache->ino, jemode_to_cpu(latest_node->mode));
- mutex_unlock(&f->sem);
- jffs2_do_clear_inode(c, f);
return -EIO;
}
if (!frag_first(&f->fragtree)) {
JFFS2_ERROR("Argh. Special inode #%u with mode 0%o has no fragments\n",
f->inocache->ino, jemode_to_cpu(latest_node->mode));
- mutex_unlock(&f->sem);
- jffs2_do_clear_inode(c, f);
return -EIO;
}
/* ASSERT: f->fraglist != NULL */
@@ -1305,8 +1290,6 @@ static int jffs2_do_read_inode_internal(struct jffs2_sb_info *c,
JFFS2_ERROR("Argh. Special inode #%u with mode 0x%x had more than one node\n",
f->inocache->ino, jemode_to_cpu(latest_node->mode));
/* FIXME: Deal with it - check crc32, check for duplicate node, check times and discard the older one */
- mutex_unlock(&f->sem);
- jffs2_do_clear_inode(c, f);
return -EIO;
}
/* OK. We're happy */
@@ -1400,10 +1383,8 @@ int jffs2_do_crccheck_inode(struct jffs2_sb_info *c, struct jffs2_inode_cache *i
f->inocache = ic;
ret = jffs2_do_read_inode_internal(c, f, &n);
- if (!ret) {
- mutex_unlock(&f->sem);
- jffs2_do_clear_inode(c, f);
- }
+ mutex_unlock(&f->sem);
+ jffs2_do_clear_inode(c, f);
jffs2_xattr_do_crccheck_inode(c, ic);
kfree (f);
return ret;