*/
const char *yaffs_fs_c_version =
- "$Id: yaffs_fs.c,v 1.35 2005-12-07 22:19:26 charles Exp $";
+ "$Id: yaffs_fs.c,v 1.36 2005-12-08 00:54:55 charles Exp $";
extern const char *yaffs_guts_c_version;
#include <linux/config.h>
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,
/*dget(dentry); // try to solve directory bug */
d_add(dentry, inode);
- yaffs_GrossUnlock(dev);
-
/* return dentry; */
return NULL;
#endif
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 */
/* 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;
}
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);
error = -ENOMEM;
}
- yaffs_GrossUnlock(dev);
-
return error;
}
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;
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);
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;