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;