Index: branches/libc-0.6/src/emx/include/emx/io.h
===================================================================
--- branches/libc-0.6/src/emx/include/emx/io.h	(revision 2521)
+++ branches/libc-0.6/src/emx/include/emx/io.h	(revision 2522)
@@ -320,4 +320,6 @@
     /** Does the file system automatically zero the new space when a file is extended? */
     unsigned            fZeroNewBytes : 1;
+    /** Does the file system provide sufficient EA support for UNIX attributes? */
+    unsigned            fUnixEAs : 1;
     /** Device number of the device the filesystem resides on.
      * On OS/2 the device number is derived from the driveletter. */
Index: branches/libc-0.6/src/emx/src/lib/sys/b_fs.h
===================================================================
--- branches/libc-0.6/src/emx/src/lib/sys/b_fs.h	(revision 2521)
+++ branches/libc-0.6/src/emx/src/lib/sys/b_fs.h	(revision 2522)
@@ -411,4 +411,21 @@
 
 /**
+ * Gets the fs info object for the specfied path.
+ *
+ * @returns Pointer to info object for the path, if it got one.
+ * @param   pszNativePath   The native path as returned by the resolver.
+ */
+__LIBC_PFSINFO __libc_back_fsInfoObjByPath(const char *pszNativePath);
+
+/**
+ * Gets the fs info object for the specfied path, with cache.
+ *
+ * @returns Pointer to info object for the path, if it got one.
+ * @param   pszNativePath   The native path as returned by the resolver.
+ * @param   pCached         An cached fs info object reference. Can be NULL.
+ */
+__LIBC_PFSINFO __libc_back_fsInfoObjByPathCached(const char *pszNativePath, __LIBC_PFSINFO pCached);
+
+/**
  * Adds a reference to an existing FS info object.
  *
@@ -428,4 +445,12 @@
 void __libc_back_fsInfoObjRelease(__LIBC_PFSINFO pFsInfo);
 
+/**
+ * Checks if the path supports Unix EAs or not.
+ *
+ * @returns true / false.
+ * @param   pszNativePath       The native path to check.
+ */
+int __libc_back_fsInfoSupportUnixEAs(const char *pszNativePath);
+
 __END_DECLS
 
Index: branches/libc-0.6/src/emx/src/lib/sys/b_fsDirCreate.c
===================================================================
--- branches/libc-0.6/src/emx/src/lib/sys/b_fsDirCreate.c	(revision 2521)
+++ branches/libc-0.6/src/emx/src/lib/sys/b_fsDirCreate.c	(revision 2522)
@@ -69,5 +69,5 @@
      */
     PEAOP2 pEaOp2 = NULL;
-    if (__predict_true(!__libc_gfNoUnix))
+    if (__predict_true(__libc_back_fsInfoSupportUnixEAs(szNativePath)))
     {
         Mode &= ~__libc_gfsUMask;
Index: branches/libc-0.6/src/emx/src/lib/sys/b_fsFileModeSetFH.c
===================================================================
--- branches/libc-0.6/src/emx/src/lib/sys/b_fsFileModeSetFH.c	(revision 2521)
+++ branches/libc-0.6/src/emx/src/lib/sys/b_fsFileModeSetFH.c	(revision 2522)
@@ -121,5 +121,7 @@
          * If in unix mode we'll have to update/add the MODE too.
          */
-        if (!__libc_gfNoUnix)
+        if (    !__libc_gfNoUnix
+            &&  pFH->pFsInfo
+            &&  pFH->pFsInfo->fUnixEAs)
         {
             struct stat st = {0};
Index: branches/libc-0.6/src/emx/src/lib/sys/b_fsFileStatFH.c
===================================================================
--- branches/libc-0.6/src/emx/src/lib/sys/b_fsFileStatFH.c	(revision 2521)
+++ branches/libc-0.6/src/emx/src/lib/sys/b_fsFileStatFH.c	(revision 2522)
@@ -71,4 +71,5 @@
         LIBCLOG_ERROR_RETURN_INT(rc);
 
+    int fUnixEAs = !__libc_gfNoUnix && pFH->pFsInfo && pFH->pFsInfo->fUnixEAs;
     if (/*!pFH->pOps*/ 1)
     {
@@ -110,5 +111,8 @@
             if (__libc_gpfnDosOpenL)
             {
-                rc = DosQueryFileInfo(fh, FIL_QUERYEASIZEL, &info, sizeof(info.fsts4L));
+                if (fUnixEAs)
+                    rc = DosQueryFileInfo(fh, FIL_QUERYEASIZEL, &info, sizeof(info.fsts4L));
+                else
+                    rc = -1;
                 if (rc)
                 {
@@ -121,5 +125,8 @@
 #endif
             {
-                rc = DosQueryFileInfo(fh, FIL_QUERYEASIZE, &info, sizeof(info.fsts4));
+                if (fUnixEAs)
+                    rc = DosQueryFileInfo(fh, FIL_QUERYEASIZE, &info, sizeof(info.fsts4));
+                else
+                    rc = -1;
                 if (rc)
                 {
@@ -175,5 +182,5 @@
 
             /* If in unix mode we'll check the EAs (if any). */
-            if (    !__libc_gfNoUnix
+            if (   fUnixEAs
                 && (fLarge ? info.fsts4L.cbList : info.fsts4.cbList) >= LIBC_UNIX_EA_MIN)
                 __libc_back_fsUnixAttribsGet(fh, pFH->pszNativePath, pStat);
Index: branches/libc-0.6/src/emx/src/lib/sys/b_fsNativeFileModeSet.c
===================================================================
--- branches/libc-0.6/src/emx/src/lib/sys/b_fsNativeFileModeSet.c	(revision 2521)
+++ branches/libc-0.6/src/emx/src/lib/sys/b_fsNativeFileModeSet.c	(revision 2522)
@@ -89,14 +89,21 @@
     FS_SAVE_LOAD();
     int rc;
-#if OFF_MAX > LONG_MAX
-    if (__libc_gpfnDosOpenL)
-    {
-        rc = DosQueryPathInfo((PCSZ)pszNativePath, FIL_QUERYEASIZEL, &info, sizeof(info.fsts4L));
-        fLarge = 1;
+    const int fUnixEAs = __libc_back_fsInfoSupportUnixEAs(pszNativePath);
+    if (fUnixEAs)
+    {
+#if OFF_MAX > LONG_MAX
+        if (__libc_gpfnDosOpenL)
+        {
+            rc = DosQueryPathInfo((PCSZ)pszNativePath, FIL_QUERYEASIZEL, &info, sizeof(info.fsts4L));
+            fLarge = 1;
+        }
+        else
+#endif
+            rc = DosQueryPathInfo((PCSZ)pszNativePath, FIL_QUERYEASIZE, &info, sizeof(info.fsts4));
+        /* If the file is open in write mode, we cannot even get the EA size. stupid.
+         * It'll fail with ERROR_SHARING_VIOLATION, which we handle rigth below. */
     }
     else
-#endif
-        rc = DosQueryPathInfo((PCSZ)pszNativePath, FIL_QUERYEASIZE, &info, sizeof(info.fsts4));
-    /* Now, if the file is open in write mode, we cannot even get the EA size. stupid. */
+        rc = ERROR_SHARING_VIOLATION; /* take the fallback path if we don't want EAs. */
     if (rc == ERROR_SHARING_VIOLATION)
     {
@@ -150,5 +157,5 @@
      * If in unix mode we'll have to update/add the MODE too.
      */
-    if (!__libc_gfNoUnix)
+    if (fUnixEAs)
     {
         struct stat st = {0};
Index: branches/libc-0.6/src/emx/src/lib/sys/b_fsNativeFileStat.c
===================================================================
--- branches/libc-0.6/src/emx/src/lib/sys/b_fsNativeFileStat.c	(revision 2521)
+++ branches/libc-0.6/src/emx/src/lib/sys/b_fsNativeFileStat.c	(revision 2522)
@@ -86,4 +86,5 @@
      */
     /** @todo copy device check from the path resolver. */
+
     /*
      * Get path info.
@@ -91,13 +92,22 @@
     FS_SAVE_LOAD();
     int rc;
-#if OFF_MAX > LONG_MAX
-    if (__libc_gpfnDosOpenL)
-    {
-        rc = DosQueryPathInfo((PCSZ)pszNativePath, FIL_QUERYEASIZEL, &info, sizeof(info.fsts4L));
-        fLarge = 1;
-    }
-    else
-#endif
-        rc = DosQueryPathInfo((PCSZ)pszNativePath, FIL_QUERYEASIZE, &info, sizeof(info.fsts4));
+    const int fUnixEAs = __libc_back_fsInfoSupportUnixEAs(pszNativePath);
+    if (fUnixEAs)
+    {
+#if OFF_MAX > LONG_MAX
+        if (__libc_gpfnDosOpenL)
+        {
+            rc = DosQueryPathInfo((PCSZ)pszNativePath, FIL_QUERYEASIZEL, &info, sizeof(info.fsts4L));
+            fLarge = 1;
+        }
+        else
+#endif
+            rc = DosQueryPathInfo((PCSZ)pszNativePath, FIL_QUERYEASIZE, &info, sizeof(info.fsts4));
+        /* If the file is open in write mode, we cannot even get the EA size. stupid.
+         * It'll fail with ERROR_SHARING_VIOLATION, which we handle rigth below. */
+    }
+    else
+        rc = ERROR_SHARING_VIOLATION; /* take the fallback path if we don't want EAs. */
+
     /* Now, if the file is open in write mode, we cannot even get the EA size. stupid. */
     if (rc == ERROR_SHARING_VIOLATION)
@@ -198,5 +208,5 @@
     /* If in unix mode we'll check the EAs (if any). */
     rc = 1;
-    if (    !__libc_gfNoUnix
+    if (    fUnixEAs
         && (fLarge ? info.fsts4L.cbList : info.fsts4.cbList) >= LIBC_UNIX_EA_MIN)
         rc = __libc_back_fsUnixAttribsGet(-1, pszNativePath, pStat);
Index: branches/libc-0.6/src/emx/src/lib/sys/b_ioFileOpen.c
===================================================================
--- branches/libc-0.6/src/emx/src/lib/sys/b_ioFileOpen.c	(revision 2521)
+++ branches/libc-0.6/src/emx/src/lib/sys/b_ioFileOpen.c	(revision 2522)
@@ -259,5 +259,6 @@
         Mode &= ACCESSPERMS;
         Mode |= S_IFREG;
-        if (flOpenFlags & (OPEN_ACTION_CREATE_IF_NEW | OPEN_ACTION_REPLACE_IF_EXISTS))
+        if (    (flOpenFlags & (OPEN_ACTION_CREATE_IF_NEW | OPEN_ACTION_REPLACE_IF_EXISTS))
+            &&  __libc_back_fsInfoSupportUnixEAs(szNativePath))
         {
             pEaOp2 = alloca(sizeof(EAOP2) + sizeof(__libc_gFsUnixAttribsCreateFEA2List));
Index: branches/libc-0.6/src/emx/src/lib/sys/b_nativeSymlinkCreate.c
===================================================================
--- branches/libc-0.6/src/emx/src/lib/sys/b_nativeSymlinkCreate.c	(revision 2521)
+++ branches/libc-0.6/src/emx/src/lib/sys/b_nativeSymlinkCreate.c	(revision 2522)
@@ -58,5 +58,5 @@
     BYTE    fSymlinkEA;
     BYTE    cbSymlinkName;
-    USHORT  usSymlinkValue;
+    USHORT  cbSymlinkValue;
     CHAR    szSymlinkName[sizeof(EA_SYMLINK)];
     USHORT  usSymlinkType;
@@ -112,4 +112,10 @@
 
     /*
+     * Do we have UnixEAs on this path?
+     */
+    if (__predict_false(!__libc_back_fsInfoSupportUnixEAs(pszNativePath)))
+        LIBCLOG_ERROR_RETURN(-ENOTSUP, "ret -ENOTSUP - no Unix EAs on '%s'\n", pszNativePath);
+
+    /*
      * Allocate FEA buffer.
      */
@@ -126,6 +132,7 @@
     *pFEas = __libc_gFsUnixAttribsCreateSymlinkFEA2List;
     __libc_back_fsUnixAttribsInit(&pFEas->Core, pszNativePath, S_IFLNK | S_IRWXO | S_IRWXG | S_IRWXU);
-    pFEas->Core.cbList = cchTarget + sizeof(USHORT) * 2;
-    pFEas->cbSymlinkData = cchTarget;
+    pFEas->Core.cbList = cchTarget + sizeof(__libc_gFsUnixAttribsCreateSymlinkFEA2List) - 1;
+    pFEas->cbSymlinkValue += cchTarget;
+    pFEas->cbSymlinkData  = cchTarget;
     memcpy(pFEas->szSymlink, pszTarget, cchTarget);
 
Index: branches/libc-0.6/src/emx/src/lib/sys/fs.c
===================================================================
--- branches/libc-0.6/src/emx/src/lib/sys/fs.c	(revision 2521)
+++ branches/libc-0.6/src/emx/src/lib/sys/fs.c	(revision 2522)
@@ -637,11 +637,13 @@
     LIBCLOG_ENTER("pszUserPath=%p:{%s} pszNativePath=%p *pfInUnixTree=%p\n",
                   (void *)pszUserPath, pszUserPath, (void *)pszNativePath, (void *)pfInUnixTree);
-    const char *pszUserPathIn = pszUserPath;
-    char        _achBuffer[SIZEOF_ACHBUFFER + 4];
-    char       *pachBuffer = (char *)((uintptr_t)&_achBuffer[3] & ~3);
-    unsigned    cLoopsLeft = 8;
-    int         fInUnixTree = __libc_gfInUnixTree;
-    int         rcRet = 0;
-    HDIR        hDir = HDIR_CREATE;
+    const char     *pszUserPathIn = pszUserPath;
+    char            _achBuffer[SIZEOF_ACHBUFFER + 4];
+    char           *pachBuffer = (char *)((uintptr_t)&_achBuffer[3] & ~3);
+    unsigned        cLoopsLeft = 8;
+    int             fInUnixTree = __libc_gfInUnixTree;
+    int             rcRet = 0;
+    HDIR            hDir = HDIR_CREATE;
+    __LIBC_PFSINFO  pFsInfo = NULL;
+    int             fUnixEAs;
     FS_VAR()
     FS_SAVE_LOAD();
@@ -889,4 +891,7 @@
             iRoot = psz - pszNativePath;
             psz = strchr(psz, '/');
+
+            /* We don't do UNIX EAs on UNCs */
+            fUnixEAs = 0;
         }
         else
@@ -898,4 +903,9 @@
             pszPrev = &pszNativePath[iRoot + 1];
             psz = strchr(pszPrev, '/');
+
+            /* Unix EAs? */
+            pFsInfo = __libc_back_fsInfoObjByPathCached(pszNativePath, pFsInfo);
+            LIBC_ASSERTM(pFsInfo, "%s\n", pszNativePath);
+            fUnixEAs = pFsInfo ? pFsInfo->fUnixEAs : 0;
         }
         LIBC_ASSERTM(pszPrev - pszNativePath >= iRoot, "iRoot=%d  pszPrev offset %d  pszNativePath=%s\n", iRoot, pszPrev - pszNativePath, pszNativePath);
@@ -975,7 +985,10 @@
              * This is a little bit messed up since we'll have to use wildcard for
              * getting the casing resolved.
+             *
+             * The two find buffers are assumed to be equal down thru attrFile.
              */
             //LIBC_ASSERT(psz - pszNativePath == cchNativePath); - figure this one.
-            PFILEFINDBUF4 pFindBuf = (PFILEFINDBUF4)pachBuffer;
+            PFILEFINDBUF4 pFindBuf4 = (PFILEFINDBUF4)pachBuffer;
+            PFILEFINDBUF3 pFindBuf3 = (PFILEFINDBUF3)pachBuffer;
             ULONG cFiles = 1;
             char chNext = psz[1];
@@ -983,11 +996,11 @@
             psz[1] = '\0';
             int rc = DosFindFirst((PCSZ)pszNativePath, &hDir, FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY | FILE_ARCHIVED,
-                                  pFindBuf, SIZEOF_ACHBUFFER, &cFiles, FIL_QUERYEASIZE);
+                                  pachBuffer, SIZEOF_ACHBUFFER, &cFiles, fUnixEAs ? FIL_QUERYEASIZE : FIL_STANDARD);
             psz[0] = '\0';
             psz[1] = chNext;
             if (rc || cFiles == 0)
                 hDir = HDIR_CREATE;
-            while (!rc && cFiles == 1 && pFindBuf->cchName != psz - pszPrev)
-                rc = DosFindNext(hDir, pFindBuf, SIZEOF_ACHBUFFER, &cFiles);
+            while (!rc && cFiles == 1 && (fUnixEAs ? pFindBuf4->cchName : pFindBuf3->cchName) != psz - pszPrev)
+                rc = DosFindNext(hDir, pachBuffer, SIZEOF_ACHBUFFER, &cFiles);
             if (rc || cFiles == 0)
             {
@@ -1002,10 +1015,10 @@
                 break;
             }
-            memcpy(pszPrev, pFindBuf->achName, psz - pszPrev);
-            int     fIsDirectory = (pFindBuf->attrFile & FILE_DIRECTORY) != 0;
+            memcpy(pszPrev, fUnixEAs ? pFindBuf4->achName : pFindBuf3->achName, psz - pszPrev);
+            int     fIsDirectory = (pFindBuf4->attrFile & FILE_DIRECTORY) != 0;
 
             /*
              * Try querying the symlink EA value.
-             * (This operation will reuse the achBuffer overwriting the pFindBuf data!)
+             * (This operation will reuse the achBuffer overwriting the pFindBuf[3/4] data!)
              *
              * Yeah, we could do this in the same operation as the DosFindFirst() but
@@ -1017,8 +1030,9 @@
              * cases anyway... very nice.
              */
-            if (    pFindBuf->cbList > sizeof(USHORT) * 2 + 1
+            if (    fUnixEAs
+                &&   pFindBuf4->cbList > sizeof(USHORT) * 2 + 1
                 &&  (   (fFlags & BACKFS_FLAGS_RESOLVE_FULL)
                      || chSlash)
-                &&  !(pFindBuf->attrFile & FILE_DIRECTORY))
+                &&  !(pFindBuf4->attrFile & FILE_DIRECTORY))
             {
                 PEAOP2  pEaOp2 = (PEAOP2)pachBuffer;
@@ -1188,8 +1202,10 @@
 
     /*
-     * Cleanup find handle.
+     * Cleanup find handle and fs object.
      */
     if (hDir != HDIR_CREATE)
         DosFindClose(hDir);
+    if (pFsInfo)
+        __libc_back_fsInfoObjRelease(pFsInfo);
     FS_RESTORE();
 
@@ -1502,4 +1518,5 @@
     /* init the structure */
     pFsInfo->fZeroNewBytes = 0;
+    pFsInfo->fUnixEAs = 0;
     pFsInfo->Dev = Dev;
     pFsInfo->szName[0] = '\0';
@@ -1517,9 +1534,34 @@
     if (    !strcmp(pFsInfo->szName, "JFS")
         ||  !strcmp(pFsInfo->szName, "HPFS")
-        ||  !strcmp(pFsInfo->szName, "FAT")
-        ||  !strcmp(pFsInfo->szName, "LAN"))
-        pFsInfo->fZeroNewBytes = 1;   /* RAMFS does not do this. */
-    LIBCLOG_MSG2("fsInfoObjUpdate: dev:%#x mp:%s fsd:%s fZeroNewBytes=%d\n",
-                 pFsInfo->Dev, pFsInfo->szMountpoint, pFsInfo->szName, pFsInfo->fZeroNewBytes);
+        ||  !strcmp(pFsInfo->szName, "FAT"))
+    {
+        pFsInfo->fZeroNewBytes  = 1;
+        pFsInfo->fUnixEAs       = 1;
+    }
+    else if (!strcmp(pFsInfo->szName, "LAN"))
+    {
+        /* should find a way of getting the remote fs... */
+        pFsInfo->fZeroNewBytes  = 1;    /* for performance reasons, assume it zeros. */
+        pFsInfo->fUnixEAs       = 0;
+    }
+    else if (!strcmp(pFsInfo->szName, "RAMFS"))
+    {
+        pFsInfo->fZeroNewBytes  = 0;
+        pFsInfo->fUnixEAs       = 1; /* but it doesn't zero */
+    }
+    /*else if (!strcmp(pFsInfo->szName, "FAT32"))
+    {
+        pFsInfo->fZeroNewBytes  = 0;
+        pFsInfo->fUnixEAs       = 0;
+    }*/
+    else
+    {
+        pFsInfo->fZeroNewBytes  = 0;
+        pFsInfo->fUnixEAs       = 0;
+    }
+
+    LIBCLOG_MSG2("fsInfoObjUpdate: dev:%#x mp:%s fsd:%s fZeroNewBytes=%d fUnixEAs=%d\n",
+                 pFsInfo->Dev, pFsInfo->szMountpoint, pFsInfo->szName, pFsInfo->fZeroNewBytes,
+                 pFsInfo->fUnixEAs);
     FS_RESTORE();
 }
@@ -1559,5 +1601,4 @@
 
 
-#if 0
 /**
  * Gets the fs info object for the specfied path.
@@ -1582,5 +1623,34 @@
     return __libc_back_fsInfoObjByDev(Dev);
 }
-#endif
+
+
+/**
+ * Gets the fs info object for the specfied path, with cache.
+ *
+ * @returns Pointer to info object for the path, if it got one.
+ * @param   pszNativePath   The native path as returned by the resolver.
+ * @param   pCached         An cached fs info object reference. Can be NULL.
+ */
+__LIBC_PFSINFO __libc_back_fsInfoObjByPathCached(const char *pszNativePath, __LIBC_PFSINFO pCached)
+{
+    /*
+     * Calc device.
+     */
+    dev_t   Dev;
+    char    chDrv = *pszNativePath;
+    if (chDrv == '/' || chDrv == '\\')
+        Dev = makedev('U', 0);          /* U as in UNC */
+    else
+    {
+        LIBC_ASSERT(chDrv >= 'A' && chDrv <= 'Z');
+        Dev = makedev('V', chDrv);      /* V as in Volume */
+    }
+    if (!pCached)
+        return __libc_back_fsInfoObjByDev(Dev);
+    if (pCached->Dev == Dev)
+        return pCached;
+    __libc_back_fsInfoObjRelease(pCached);
+    return __libc_back_fsInfoObjByDev(Dev);
+}
 
 
@@ -1617,4 +1687,22 @@
         LIBC_ASSERT(cRefs > 1); (void)cRefs;
     }
+}
+
+
+/**
+ * Checks if the path supports Unix EAs or not.
+ *
+ * @returns true / false.
+ * @param   pszNativePath       The native path to check.
+ */
+int __libc_back_fsInfoSupportUnixEAs(const char *pszNativePath)
+{
+    if (__libc_gfNoUnix)
+        return 0;
+
+    __LIBC_PFSINFO pFsInfo = __libc_back_fsInfoObjByPath(pszNativePath);
+    const int fUnixEAs = pFsInfo && pFsInfo->fUnixEAs;
+    __libc_back_fsInfoObjRelease(pFsInfo);
+    return fUnixEAs;
 }
 
