Changeset 4dc16ea in rtems


Ignore:
Timestamp:
Feb 26, 2014, 2:27:40 AM (6 years ago)
Author:
Brian Norris <computersforpeace@…>
Branches:
master
Children:
410dd26
Parents:
8e55f0d
git-author:
Brian Norris <computersforpeace@…> (02/26/14 02:27:40)
git-committer:
Sebastian Huber <sebastian.huber@…> (07/16/18 05:22:12)
Message:

jffs2: fix unbalanced locking

Li Zefan reported an unbalanced locking issue, found by his
internal debugging feature on runtime. The particular case he was
looking at doesn't lead to a deadlock, as the structure that this lock
is embedded in is freed on error. But we should straighten out the error
handling.

Because several callers of jffs2_do_read_inode_internal() /
jffs2_do_read_inode() already handle the locking/unlocking and inode
clearing at their own level, let's just push any unlocks/clearing down
to the caller. This consistency is much easier to verify.

Reported-by: Li Zefan <lizefan@…>
Cc: David Woodhouse <dwmw2@…>
Cc: Artem Bityutskiy <artem.bityutskiy@…>
Cc: Andrew Morton <akpm@…>
Signed-off-by: Brian Norris <computersforpeace@…>

File:
1 edited

Legend:

Unmodified
Added
Removed
  • cpukit/libfs/src/jffs2/src/readinode.c

    r8e55f0d r4dc16ea  
    12131213                        ret, retlen, sizeof(*latest_node));
    12141214                /* FIXME: If this fails, there seems to be a memory leak. Find it. */
    1215                 mutex_unlock(&f->sem);
    1216                 jffs2_do_clear_inode(c, f);
    1217                 return ret?ret:-EIO;
     1215                return ret ? ret : -EIO;
    12181216        }
    12191217
     
    12221220                JFFS2_ERROR("CRC failed for read_inode of inode %u at physical location 0x%x\n",
    12231221                        f->inocache->ino, ref_offset(rii.latest_ref));
    1224                 mutex_unlock(&f->sem);
    1225                 jffs2_do_clear_inode(c, f);
    12261222                return -EIO;
    12271223        }
     
    12601256                         * operation. */
    12611257                        uint32_t csize = je32_to_cpu(latest_node->csize);
    1262                         if (csize > JFFS2_MAX_NAME_LEN) {
    1263                                 mutex_unlock(&f->sem);
    1264                                 jffs2_do_clear_inode(c, f);
     1258                        if (csize > JFFS2_MAX_NAME_LEN)
    12651259                                return -ENAMETOOLONG;
    1266                         }
    12671260                        f->target = kmalloc(csize + 1, GFP_KERNEL);
    12681261                        if (!f->target) {
    12691262                                JFFS2_ERROR("can't allocate %u bytes of memory for the symlink target path cache\n", csize);
    1270                                 mutex_unlock(&f->sem);
    1271                                 jffs2_do_clear_inode(c, f);
    12721263                                return -ENOMEM;
    12731264                        }
     
    12811272                                kfree(f->target);
    12821273                                f->target = NULL;
    1283                                 mutex_unlock(&f->sem);
    1284                                 jffs2_do_clear_inode(c, f);
    12851274                                return ret;
    12861275                        }
     
    12991288                        JFFS2_ERROR("Argh. Special inode #%u with mode 0%o had metadata node\n",
    13001289                               f->inocache->ino, jemode_to_cpu(latest_node->mode));
    1301                         mutex_unlock(&f->sem);
    1302                         jffs2_do_clear_inode(c, f);
    13031290                        return -EIO;
    13041291                }
     
    13061293                        JFFS2_ERROR("Argh. Special inode #%u with mode 0%o has no fragments\n",
    13071294                               f->inocache->ino, jemode_to_cpu(latest_node->mode));
    1308                         mutex_unlock(&f->sem);
    1309                         jffs2_do_clear_inode(c, f);
    13101295                        return -EIO;
    13111296                }
     
    13151300                               f->inocache->ino, jemode_to_cpu(latest_node->mode));
    13161301                        /* FIXME: Deal with it - check crc32, check for duplicate node, check times and discard the older one */
    1317                         mutex_unlock(&f->sem);
    1318                         jffs2_do_clear_inode(c, f);
    13191302                        return -EIO;
    13201303                }
     
    14101393
    14111394        ret = jffs2_do_read_inode_internal(c, f, &n);
    1412         if (!ret) {
    1413                 mutex_unlock(&f->sem);
    1414                 jffs2_do_clear_inode(c, f);
    1415         }
     1395        mutex_unlock(&f->sem);
     1396        jffs2_do_clear_inode(c, f);
    14161397        jffs2_xattr_do_crccheck_inode(c, ic);
    14171398        kfree (f);
Note: See TracChangeset for help on using the changeset viewer.