Good Morning, all,
Charles, you'll find below the patch in a more standard form.
With this fix: YAFFS does not try anymore to take the semaphore if the
caller is the same process that already reserved it (in order to prevent
deadlocks). There should be a better solution, but this one works and
fixes our problem, so, for now, we live with it.
I hope it might be of some help...
Best regards, and have a nice day,
Jean-Loup
fs/yaffs2/yaffs_fs.c
diff -Naur yaffs_fs.c.v1_4 yaffs_fs.c.v1_5
--- yaffs_fs.c.v1_4 2008-02-18 15:16:35.000000000 +0100
+++ yaffs_fs.c.v1_5 2008-02-18 15:16:49.000000000 +0100
@@ -31,7 +31,7 @@
*/
const char *yaffs_fs_c_version =
- "$Id: yaffs_fs.c,v 1.4 2007/10/22 13:12:16 ngenevrier Exp $";
+ "$Id: yaffs_fs.c,v 1.5 2008/01/14 10:38:57 jlsabatier Exp $";
extern const char *yaffs_guts_c_version;
#include <linux/config.h>
@@ -310,7 +310,8 @@
yaffs_Device *dev = yaffs_InodeToObject(dir)->myDev;
- yaffs_GrossLock(dev);
+ if (current != dev->readdirProcess)
+ yaffs_GrossLock(dev);
T(YAFFS_TRACE_OS,
(KERN_DEBUG "yaffs_lookup for %d:%s\n",
@@ -322,8 +323,10 @@
obj = yaffs_GetEquivalentObject(obj); /* in case it was a
hardlink */
+
/* Can't hold gross lock when calling yaffs_get_inode() */
- yaffs_GrossUnlock(dev);
+ if (current != dev->readdirProcess)
+ yaffs_GrossUnlock(dev);
if (obj) {
T(YAFFS_TRACE_OS,
@@ -814,6 +817,7 @@
dev = obj->myDev;
yaffs_GrossLock(dev);
+ dev->readdirProcess = current ;
offset = f->f_pos;
@@ -883,6 +887,7 @@
up_and_out:
out:
+ dev->readdirProcess = NULL ;
yaffs_GrossUnlock(dev);
return 0;
@@ -1285,13 +1290,15 @@
T(YAFFS_TRACE_OS,
(KERN_DEBUG "yaffs_read_inode for %d\n", (int)inode->i_ino));
- yaffs_GrossLock(dev);
+ if (current != dev->readdirProcess)
+ yaffs_GrossLock(dev);
obj = yaffs_FindObjectByNumber(dev, inode->i_ino);
yaffs_FillInodeFromObject(inode, obj);
- yaffs_GrossUnlock(dev);
+ if (current != dev->readdirProcess)
+ yaffs_GrossUnlock(dev);
}
static LIST_HEAD(yaffs_dev_list);
fs/yaffs2/yaffs_guts.h
diff -Naur yaffs_guts.h.v1_1 yaffs_guts.h.v1_2
--- yaffs_guts.h.v1_1 2008-02-18 15:23:44.000000000 +0100
+++ yaffs_guts.h.v1_2 2008-02-18 15:23:32.000000000 +0100
@@ -14,7 +14,7 @@
*
* Note: Only YAFFS headers are LGPL, YAFFS C code is covered by GPL.
*
- * $Id: yaffs_guts.h,v 1.1 2006/06/09 06:42:35 pvillet Exp $
+ * $Id: yaffs_guts.h,v 1.2 2008/01/14 10:38:57 jlsabatier Exp $
*/
#ifndef __YAFFS_GUTS_H__
@@ -653,6 +653,8 @@
unsigned sequenceNumber; /* Sequence number of currently
allocating block */
unsigned oldestDirtySequence;
+ struct task_struct *readdirProcess;
+
};
typedef struct yaffs_DeviceStruct yaffs_Device;