Mercurial > yaffs-ecoscentric
changeset 109:1cbbe1e003ac
Apply Reed's deadlocking fix (manually applied)
| author | charles |
|---|---|
| date | Thu, 08 Dec 2005 00:54:55 +0000 |
| parents | 0bd1ed47d35c |
| children | b2372a63adc0 |
| files | yaffs_fs.c |
| diffstat | 1 files changed, 16 insertions(+), 9 deletions(-) [+] |
line wrap: on
line diff
--- a/yaffs_fs.c +++ b/yaffs_fs.c @@ -309,6 +309,9 @@ static struct dentry *yaffs_lookup(struc dentry->d_name.name); obj = yaffs_GetEquivalentObject(obj); /* in case it was a hardlink */ + + /* Can't hold gross lock when calling yaffs_get_inode() */ + yaffs_GrossUnlock(dev); if (obj) { T(YAFFS_TRACE_OS, @@ -325,8 +328,6 @@ static struct dentry *yaffs_lookup(struc /*dget(dentry); // try to solve directory bug */ d_add(dentry, inode); - yaffs_GrossUnlock(dev); - /* return dentry; */ return NULL; #endif @@ -336,7 +337,6 @@ static struct dentry *yaffs_lookup(struc T(YAFFS_TRACE_OS, (KERN_DEBUG "yaffs_lookup not found\n")); } - yaffs_GrossUnlock(dev); /* added NCB for 2.5/6 compatability - forces add even if inode is * NULL which creates dentry hash */ @@ -725,6 +725,7 @@ struct inode *yaffs_get_inode(struct sup /* NB Side effect: iget calls back to yaffs_read_inode(). */ /* iget also increments the inode's i_count */ + /* NB You can't be holding grossLock or deadlock will happen! */ return inode; } @@ -940,6 +941,9 @@ static int yaffs_mknod(struct inode *dir obj = NULL; /* Do we ever get here? */ break; } + + /* Can not call yaffs_get_inode() with gross lock held */ + yaffs_GrossUnlock(dev); if (obj) { inode = yaffs_get_inode(dir->i_sb, mode, rdev, obj); @@ -954,8 +958,6 @@ static int yaffs_mknod(struct inode *dir error = -ENOMEM; } - yaffs_GrossUnlock(dev); - return error; } @@ -1236,8 +1238,9 @@ static int yaffs_statfs(struct super_blo static void yaffs_read_inode(struct inode *inode) { - /* NB This is called as a side effect of other functions and - * thus gross locking should always be in place already. + /* NB This is called as a side effect of other functions, but + * we had to release the lock to prevent deadlocks, so + * need to lock again. */ yaffs_Object *obj; @@ -1246,10 +1249,13 @@ static void yaffs_read_inode(struct inod T(YAFFS_TRACE_OS, (KERN_DEBUG "yaffs_read_inode for %d\n", (int)inode->i_ino)); + yaffs_GrossLock(dev); + obj = yaffs_FindObjectByNumber(dev, inode->i_ino); yaffs_FillInodeFromObject(inode, obj); + yaffs_GrossUnlock(dev); } static LIST_HEAD(yaffs_dev_list); @@ -1481,14 +1487,15 @@ static struct super_block *yaffs_interna T(YAFFS_TRACE_OS, ("yaffs_read_super: guts initialised %s\n", (err == YAFFS_OK) ? "OK" : "FAILED")); + + /* Release lock before yaffs_get_inode() */ + yaffs_GrossUnlock(dev); /* Create root inode */ if (err == YAFFS_OK) inode = yaffs_get_inode(sb, S_IFDIR | 0755, 0, yaffs_Root(dev)); - yaffs_GrossUnlock(dev); - if (!inode) return NULL;
