ignite-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From a.@apache.org
Subject [06/40] ignite git commit: IGNITE-3645: IGFS: Local secondary: Implemented update() operation. This closes #1003.
Date Mon, 17 Oct 2016 17:59:03 GMT
IGNITE-3645: IGFS: Local secondary: Implemented update() operation. This closes #1003.


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/9f211e41
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/9f211e41
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/9f211e41

Branch: refs/heads/ignite-ssl-hotfix
Commit: 9f211e413332931f0fb1190744ddd7c7f38fd213
Parents: 0b66d2d
Author: tledkov-gridgain <tledkov@gridgain.com>
Authored: Mon Oct 3 12:26:12 2016 +0300
Committer: vozerov-gridgain <vozerov@gridgain.com>
Committed: Mon Oct 3 12:26:12 2016 +0300

----------------------------------------------------------------------
 .../local/LocalIgfsSecondaryFileSystem.java     |  90 ++-
 .../internal/processors/igfs/IgfsImpl.java      |  11 +-
 .../processors/igfs/IgfsMetaManager.java        |   1 -
 .../local/LocalFileSystemIgfsFile.java          |   9 +-
 .../secondary/local/LocalFileSystemUtils.java   | 142 +++++
 .../igfs/IgfsAbstractBaseSelfTest.java          |  19 +
 .../processors/igfs/IgfsAbstractSelfTest.java   |   5 +-
 .../igfs/IgfsDualAbstractSelfTest.java          |  42 +-
 ...SecondaryFileSystemDualAbstractSelfTest.java |  26 +-
 ...fsLocalSecondaryFileSystemProxySelfTest.java |   5 -
 ...IgfsLocalSecondaryFileSystemTestAdapter.java |  27 +-
 .../igfs/benchmark/IgfsBenchmark.java           | 561 +++++++++++++++++++
 ...doopIgfsSecondaryFileSystemDelegateImpl.java |   3 +-
 .../hadoop/impl/igfs/HadoopIgfsProperties.java  |   3 +
 14 files changed, 900 insertions(+), 44 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/9f211e41/modules/core/src/main/java/org/apache/ignite/igfs/secondary/local/LocalIgfsSecondaryFileSystem.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/igfs/secondary/local/LocalIgfsSecondaryFileSystem.java b/modules/core/src/main/java/org/apache/ignite/igfs/secondary/local/LocalIgfsSecondaryFileSystem.java
index 1775db6..ef00bea 100644
--- a/modules/core/src/main/java/org/apache/ignite/igfs/secondary/local/LocalIgfsSecondaryFileSystem.java
+++ b/modules/core/src/main/java/org/apache/ignite/igfs/secondary/local/LocalIgfsSecondaryFileSystem.java
@@ -26,8 +26,10 @@ import org.apache.ignite.igfs.IgfsPathIsNotDirectoryException;
 import org.apache.ignite.igfs.IgfsPathNotFoundException;
 import org.apache.ignite.igfs.secondary.IgfsSecondaryFileSystem;
 import org.apache.ignite.igfs.secondary.IgfsSecondaryFileSystemPositionedReadable;
+import org.apache.ignite.internal.processors.igfs.IgfsUtils;
 import org.apache.ignite.internal.processors.igfs.secondary.local.LocalFileSystemIgfsFile;
 import org.apache.ignite.internal.processors.igfs.secondary.local.LocalFileSystemSizeVisitor;
+import org.apache.ignite.internal.processors.igfs.secondary.local.LocalFileSystemUtils;
 import org.apache.ignite.internal.processors.igfs.secondary.local.LocalIgfsSecondaryFileSystemPositionedReadable;
 import org.apache.ignite.internal.util.typedef.F;
 import org.apache.ignite.internal.util.typedef.internal.U;
@@ -44,6 +46,7 @@ import java.nio.file.Files;
 import java.nio.file.LinkOption;
 import java.nio.file.Path;
 import java.nio.file.attribute.BasicFileAttributes;
+import java.nio.file.attribute.PosixFileAttributes;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.Map;
@@ -76,7 +79,14 @@ public class LocalIgfsSecondaryFileSystem implements IgfsSecondaryFileSystem, Li
 
     /** {@inheritDoc} */
     @Nullable @Override public IgfsFile update(IgfsPath path, Map<String, String> props) {
-        throw new UnsupportedOperationException("Update operation is not yet supported.");
+        File f = fileForPath(path);
+
+        if (!f.exists())
+            return null;
+
+        updatePropertiesIfNeeded(path, props);
+
+        return info(path);
     }
 
     /** {@inheritDoc} */
@@ -157,6 +167,8 @@ public class LocalIgfsSecondaryFileSystem implements IgfsSecondaryFileSystem, Li
     /** {@inheritDoc} */
     @Override public void mkdirs(IgfsPath path, @Nullable Map<String, String> props) {
         mkdirs(path);
+
+        updatePropertiesIfNeeded(path, props);
     }
 
     /**
@@ -258,7 +270,23 @@ public class LocalIgfsSecondaryFileSystem implements IgfsSecondaryFileSystem, Li
     /** {@inheritDoc} */
     @Override public OutputStream create(IgfsPath path, int bufSize, boolean overwrite, int replication,
         long blockSize, @Nullable Map<String, String> props) {
-        return create0(path, overwrite);
+        OutputStream os = create0(path, overwrite);
+
+        try {
+            updatePropertiesIfNeeded(path, props);
+
+            return os;
+        }
+        catch (Exception err) {
+            try {
+                os.close();
+            }
+            catch (IOException closeErr) {
+                err.addSuppressed(closeErr);
+            }
+
+            throw err;
+        }
     }
 
     /** {@inheritDoc} */
@@ -269,11 +297,30 @@ public class LocalIgfsSecondaryFileSystem implements IgfsSecondaryFileSystem, Li
 
             boolean exists = file.exists();
 
-            if (exists)
-                return new FileOutputStream(file, true);
+            if (exists) {
+                OutputStream os = new FileOutputStream(file, true);
+
+                try {
+                    updatePropertiesIfNeeded(path, props);
+
+                    return os;
+                }
+                catch (Exception err) {
+                    try {
+                        os.close();
+
+                        throw err;
+                    }
+                    catch (IOException closeErr) {
+                        err.addSuppressed(closeErr);
+
+                        throw err;
+                    }
+                }
+            }
             else {
                 if (create)
-                    return create0(path, false);
+                    return create(path, bufSize, false, 0, 0, props);
                 else
                     throw new IgfsPathNotFoundException("Failed to append to file because it doesn't exist: " + path);
             }
@@ -285,17 +332,21 @@ public class LocalIgfsSecondaryFileSystem implements IgfsSecondaryFileSystem, Li
 
     /** {@inheritDoc} */
     @Override public IgfsFile info(final IgfsPath path) {
-        File f = fileForPath(path);
+        File file = fileForPath(path);
 
-        if (!f.exists())
+        if (!file.exists())
             return null;
 
-        boolean isDir = f.isDirectory();
+        boolean isDir = file.isDirectory();
+
+        PosixFileAttributes attrs = LocalFileSystemUtils.posixAttributes(file);
+
+        Map<String, String> props = LocalFileSystemUtils.posixAttributesToMap(attrs);
 
         if (isDir)
-            return new LocalFileSystemIgfsFile(path, false, true, 0, f.lastModified(), 0, null);
+            return new LocalFileSystemIgfsFile(path, false, true, 0, file.lastModified(), 0, props);
         else
-            return new LocalFileSystemIgfsFile(path, f.isFile(), false, 0, f.lastModified(), f.length(), null);
+            return new LocalFileSystemIgfsFile(path, file.isFile(), false, 0, file.lastModified(), file.length(), props);
     }
 
     /** {@inheritDoc} */
@@ -412,4 +463,23 @@ public class LocalIgfsSecondaryFileSystem implements IgfsSecondaryFileSystem, Li
             throw handleSecondaryFsError(e, "Failed to create file [path=" + path + ", overwrite=" + overwrite + ']');
         }
     }
+
+    /**
+     * Update path properties if needed.
+     *
+     * @param path IGFS path
+     * @param props Properties map.
+     */
+    private void updatePropertiesIfNeeded(IgfsPath path, Map<String, String> props) {
+        if (props == null || props.isEmpty())
+            return;
+
+        File file = fileForPath(path);
+
+        if (!file.exists())
+            throw new IgfsPathNotFoundException("Failed to update properties for path: " + path);
+
+        LocalFileSystemUtils.updateProperties(file, props.get(IgfsUtils.PROP_GROUP_NAME),
+            props.get(IgfsUtils.PROP_PERMISSION));
+    }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/9f211e41/modules/core/src/main/java/org/apache/ignite/internal/processors/igfs/IgfsImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/igfs/IgfsImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/igfs/IgfsImpl.java
index 1dd12d9..1c985c0 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/igfs/IgfsImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/igfs/IgfsImpl.java
@@ -152,9 +152,6 @@ public final class IgfsImpl implements IgfsEx {
     /** Writers map. */
     private final ConcurrentHashMap8<IgfsPath, IgfsFileWorkerBatch> workerMap = new ConcurrentHashMap8<>();
 
-    /** Local metrics holder. */
-    private final IgfsLocalMetrics metrics = new IgfsLocalMetrics();
-
     /** Client log directory. */
     private volatile String logDir;
 
@@ -765,13 +762,11 @@ public final class IgfsImpl implements IgfsEx {
                 if (log.isDebugEnabled())
                     log.debug("Make directories: " + path);
 
-                final Map<String, String> props0 = props == null ? DFLT_DIR_META : new HashMap<>(props);
-
                 IgfsMode mode = resolveMode(path);
 
                 switch (mode) {
                     case PRIMARY:
-                        meta.mkdirs(path, props0);
+                        meta.mkdirs(path, props == null ? DFLT_DIR_META : new HashMap<>(props));
 
                         break;
 
@@ -779,12 +774,12 @@ public final class IgfsImpl implements IgfsEx {
                     case DUAL_SYNC:
                         await(path);
 
-                        meta.mkdirsDual(secondaryFs, path, props0);
+                        meta.mkdirsDual(secondaryFs, path, props);
 
                         break;
 
                     case PROXY:
-                        secondaryFs.mkdirs(path, props0);
+                        secondaryFs.mkdirs(path, props);
 
                         break;
                 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/9f211e41/modules/core/src/main/java/org/apache/ignite/internal/processors/igfs/IgfsMetaManager.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/igfs/IgfsMetaManager.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/igfs/IgfsMetaManager.java
index 89cadce..ffa502b 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/igfs/IgfsMetaManager.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/igfs/IgfsMetaManager.java
@@ -2226,7 +2226,6 @@ public class IgfsMetaManager extends IgfsManager {
             try {
                 assert fs != null;
                 assert path != null;
-                assert props != null;
 
                 if (path.parent() == null)
                     return true; // No additional handling for root directory is needed.

http://git-wip-us.apache.org/repos/asf/ignite/blob/9f211e41/modules/core/src/main/java/org/apache/ignite/internal/processors/igfs/secondary/local/LocalFileSystemIgfsFile.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/igfs/secondary/local/LocalFileSystemIgfsFile.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/igfs/secondary/local/LocalFileSystemIgfsFile.java
index 5abe4eb..400ac34 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/igfs/secondary/local/LocalFileSystemIgfsFile.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/igfs/secondary/local/LocalFileSystemIgfsFile.java
@@ -17,14 +17,13 @@
 
 package org.apache.ignite.internal.processors.igfs.secondary.local;
 
+import java.util.Collections;
+import java.util.Map;
 import org.apache.ignite.igfs.IgfsFile;
 import org.apache.ignite.igfs.IgfsPath;
 import org.apache.ignite.internal.processors.igfs.IgfsUtils;
 import org.jetbrains.annotations.Nullable;
 
-import java.util.Collections;
-import java.util.Map;
-
 /**
  * Implementation of the IgfsFile interface for the local filesystem.
  */
@@ -45,7 +44,7 @@ public class LocalFileSystemIgfsFile implements IgfsFile {
     private final long len;
 
     /** Properties. */
-    private final Map<String, String> props;
+    private Map<String, String> props;
 
     /**
      * @param path IGFS path.
@@ -63,7 +62,7 @@ public class LocalFileSystemIgfsFile implements IgfsFile {
         assert !isDir || len == 0 : "length must be 0 for dirs. [length=" + len + ']';
 
         this.path = path;
-        this.flags = IgfsUtils.flags(isDir, isFile);
+        flags = IgfsUtils.flags(isDir, isFile);
         this.blockSize = blockSize;
         this.modTime = modTime;
         this.len = len;

http://git-wip-us.apache.org/repos/asf/ignite/blob/9f211e41/modules/core/src/main/java/org/apache/ignite/internal/processors/igfs/secondary/local/LocalFileSystemUtils.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/igfs/secondary/local/LocalFileSystemUtils.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/igfs/secondary/local/LocalFileSystemUtils.java
new file mode 100644
index 0000000..59383c5
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/igfs/secondary/local/LocalFileSystemUtils.java
@@ -0,0 +1,142 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.processors.igfs.secondary.local;
+
+import org.apache.ignite.igfs.IgfsException;
+import org.apache.ignite.internal.processors.igfs.IgfsUtils;
+import org.apache.ignite.internal.util.typedef.internal.U;
+import org.jetbrains.annotations.Nullable;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.FileSystems;
+import java.nio.file.Files;
+import java.nio.file.attribute.GroupPrincipal;
+import java.nio.file.attribute.PosixFileAttributeView;
+import java.nio.file.attribute.PosixFileAttributes;
+import java.nio.file.attribute.PosixFilePermission;
+import java.nio.file.attribute.UserPrincipalLookupService;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Various utility methods for local file system.
+ */
+public class LocalFileSystemUtils {
+    /** Posix file permissions. */
+    public static final PosixFilePermission[] POSIX_PERMISSIONS = PosixFilePermission.values();
+
+    /**
+     * Update file properties.
+     *
+     * @param file File.
+     * @param grp Group.
+     * @param perm Permissions.
+     */
+    public static void updateProperties(File file, String grp, String perm) {
+        PosixFileAttributeView attrs = Files.getFileAttributeView(file.toPath(), PosixFileAttributeView.class);
+
+        if (attrs == null)
+            throw new UnsupportedOperationException("Posix file attributes not available");
+
+        if (grp != null) {
+            try {
+                UserPrincipalLookupService lookupService = FileSystems.getDefault().getUserPrincipalLookupService();
+
+                GroupPrincipal grp0 = lookupService.lookupPrincipalByGroupName(grp);
+
+                attrs.setGroup(grp0);
+            }
+            catch (IOException e) {
+                throw new IgfsException("Update the '" + IgfsUtils.PROP_GROUP_NAME + "' property is failed.", e);
+            }
+        }
+
+        if (perm != null) {
+            int perm0 = Integer.parseInt(perm, 8);
+
+            Set<PosixFilePermission> permSet = new HashSet<>(9);
+
+            for (int i = 0; i < LocalFileSystemUtils.POSIX_PERMISSIONS.length; ++i) {
+                if ((perm0 & (1 << i)) != 0)
+                    permSet.add(LocalFileSystemUtils.POSIX_PERMISSIONS[i]);
+            }
+
+            try {
+                attrs.setPermissions(permSet);
+            }
+            catch (IOException e) {
+                throw new IgfsException("Update the '" + IgfsUtils.PROP_PERMISSION + "' property is failed.", e);
+            }
+        }
+    }
+
+    /**
+     * Get POSIX attributes for file.
+     *
+     * @param file File.
+     */
+    @Nullable public static PosixFileAttributes posixAttributes(File file) {
+        PosixFileAttributes attrs = null;
+
+        try {
+            PosixFileAttributeView view = Files.getFileAttributeView(file.toPath(), PosixFileAttributeView.class);
+
+            if (view != null)
+                attrs = view.readAttributes();
+        }
+        catch (IOException e) {
+            throw new IgfsException("Failed to read POSIX attributes: " + file.getAbsolutePath(), e);
+        }
+
+        return attrs;
+    }
+
+    /**
+     * Convert POSIX attributes to property map.
+     *
+     * @param attrs Attributes view.
+     * @return IGFS properties map.
+     */
+    public static Map<String, String> posixAttributesToMap(PosixFileAttributes attrs) {
+        if (attrs == null)
+            return null;
+
+        Map<String, String> props = U.newHashMap(3);
+
+        props.put(IgfsUtils.PROP_USER_NAME, attrs.owner().getName());
+        props.put(IgfsUtils.PROP_GROUP_NAME, attrs.group().getName());
+
+        int perm = 0;
+
+        for(PosixFilePermission p : attrs.permissions())
+            perm |= (1 << 8 - p.ordinal());
+
+        props.put(IgfsUtils.PROP_PERMISSION, '0' + Integer.toOctalString(perm));
+
+        return props;
+    }
+
+    /**
+     * Private constructor.
+     */
+    private LocalFileSystemUtils() {
+        // No-op.
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/9f211e41/modules/core/src/test/java/org/apache/ignite/internal/processors/igfs/IgfsAbstractBaseSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/igfs/IgfsAbstractBaseSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/igfs/IgfsAbstractBaseSelfTest.java
index 79dc57b..374d3d3 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/igfs/IgfsAbstractBaseSelfTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/igfs/IgfsAbstractBaseSelfTest.java
@@ -871,6 +871,25 @@ public abstract class IgfsAbstractBaseSelfTest extends IgfsCommonAbstractTest {
     /**
      * Create map with properties.
      *
+     * @param grpName Group name.
+     * @param perm Permission.
+     * @return Map with properties.
+     */
+    protected Map<String, String> properties(@Nullable String grpName, @Nullable String perm) {
+        Map<String, String> props = new HashMap<>();
+
+        if (grpName != null)
+            props.put(IgfsUtils.PROP_GROUP_NAME, grpName);
+
+        if (perm != null)
+            props.put(IgfsUtils.PROP_PERMISSION, perm);
+
+        return props;
+    }
+
+    /**
+     * Create map with properties.
+     *
      * @param username User name.
      * @param grpName Group name.
      * @param perm Permission.

http://git-wip-us.apache.org/repos/asf/ignite/blob/9f211e41/modules/core/src/test/java/org/apache/ignite/internal/processors/igfs/IgfsAbstractSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/igfs/IgfsAbstractSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/igfs/IgfsAbstractSelfTest.java
index 7058954..128239d 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/igfs/IgfsAbstractSelfTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/igfs/IgfsAbstractSelfTest.java
@@ -532,7 +532,10 @@ public abstract class IgfsAbstractSelfTest extends IgfsAbstractBaseSelfTest {
      */
     @SuppressWarnings("ConstantConditions")
     public void testMkdirsParentRoot() throws Exception {
-        Map<String, String> props = properties(null, null, "0555"); // mkdirs command doesn't propagate user info.
+        Map<String, String> props = null;
+
+        if (permissionsSupported())
+            props = properties(null, null, "0555"); // mkdirs command doesn't propagate user info.
 
         igfs.mkdirs(DIR, props);
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/9f211e41/modules/core/src/test/java/org/apache/ignite/internal/processors/igfs/IgfsDualAbstractSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/igfs/IgfsDualAbstractSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/igfs/IgfsDualAbstractSelfTest.java
index 742d20c..1d6010d 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/igfs/IgfsDualAbstractSelfTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/igfs/IgfsDualAbstractSelfTest.java
@@ -970,7 +970,10 @@ public abstract class IgfsDualAbstractSelfTest extends IgfsAbstractSelfTest {
      * @throws Exception If failed.
      */
     public void testMkdirsParentPathMissingPartially() throws Exception {
-        Map<String, String> props = properties(null, null, "0555"); // mkdirs command doesn't propagate user info.
+        Map<String, String> props = null;
+
+        if (permissionsSupported())
+            props = properties(null, null, "0555"); // mkdirs command doesn't propagate user info.
 
         create(igfsSecondary, paths(DIR, SUBDIR), null);
         create(igfs, paths(DIR), null);
@@ -997,7 +1000,10 @@ public abstract class IgfsDualAbstractSelfTest extends IgfsAbstractSelfTest {
      * @throws Exception If failed.
      */
     public void testMkdrisParentPathMissing() throws Exception {
-        Map<String, String> props = properties(null, null, "0555"); // mkdirs command doesn't propagate user info.
+        Map<String, String> props = null;
+
+        if (permissionsSupported())
+            props = properties(null, null, "0555"); // mkdirs command doesn't propagate user info.
 
         create(igfsSecondary, paths(DIR, SUBDIR), null);
         create(igfs, null, null);
@@ -1131,11 +1137,19 @@ public abstract class IgfsDualAbstractSelfTest extends IgfsAbstractSelfTest {
      * @throws Exception If failed.
      */
     public void testUpdateParentRootPathMissing() throws Exception {
+        doUpdateParentRootPathMissing(properties("owner", "group", "0555"));
+    }
+
+    /**
+     * Test update when parent is the root and the path being updated is missing locally.
+     *
+     * @param props Properties.
+     * @throws Exception If failed.
+     */
+    protected void doUpdateParentRootPathMissing(Map<String, String> props) throws Exception {
         if (!propertiesSupported())
             return;
 
-        Map<String, String> props = properties("owner", "group", "0555");
-
         create(igfsSecondary, paths(DIR), null);
         create(igfs, null, null);
 
@@ -1143,8 +1157,8 @@ public abstract class IgfsDualAbstractSelfTest extends IgfsAbstractSelfTest {
 
         checkExist(igfs, DIR);
 
-        assertEquals(props, igfsSecondary.properties(DIR.toString()));
-        assertEquals(props, igfs.info(DIR).properties());
+        assertTrue(propertiesContains(igfsSecondary.properties(DIR.toString()), props));
+        assertTrue(propertiesContains(igfs.info(DIR).properties(), props));
     }
 
     /**
@@ -1613,4 +1627,20 @@ public abstract class IgfsDualAbstractSelfTest extends IgfsAbstractSelfTest {
         assertEquals(chunk.length, igfs.size(FILE));
         assertEquals(chunk.length * 2, igfs.size(SUBDIR));
     }
+
+    /**
+     * @param allProps All properties.
+     * @param checkedProps Checked properies
+     * @return {@code true} If allchecked properties are contained in the #propsAll.
+     */
+    public static boolean propertiesContains(Map<String, String> allProps, Map<String, String> checkedProps) {
+        for (String name : checkedProps.keySet())
+            if (!checkedProps.get(name).equals(allProps.get(name))) {
+                System.err.println("All properties: " + allProps);
+                System.err.println("Checked properties: " + checkedProps);
+                return false;
+            }
+
+        return true;
+    }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/9f211e41/modules/core/src/test/java/org/apache/ignite/internal/processors/igfs/IgfsLocalSecondaryFileSystemDualAbstractSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/igfs/IgfsLocalSecondaryFileSystemDualAbstractSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/igfs/IgfsLocalSecondaryFileSystemDualAbstractSelfTest.java
index 0e6fc48..8a23954 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/igfs/IgfsLocalSecondaryFileSystemDualAbstractSelfTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/igfs/IgfsLocalSecondaryFileSystemDualAbstractSelfTest.java
@@ -17,6 +17,7 @@
 
 package org.apache.ignite.internal.processors.igfs;
 
+import org.apache.ignite.IgniteSystemProperties;
 import org.apache.ignite.igfs.IgfsFile;
 import org.apache.ignite.igfs.IgfsMode;
 import org.apache.ignite.igfs.IgfsPath;
@@ -60,6 +61,13 @@ public abstract class IgfsLocalSecondaryFileSystemDualAbstractSelfTest extends I
     /** */
     private final File fileLinkSrc = new File(FS_WORK_DIR + File.separatorChar + "file");
 
+    /** */
+    private final String TEST_GROUP = System.getProperty("IGFS_LOCAL_FS_TEST_GROUP", "igfs_grp_0");
+
+    /** */
+    private final Boolean PROPERTIES_SUPPORT =
+        IgniteSystemProperties.getBoolean("IGFS_LOCAL_FS_PROPERTIES_SUPPORT", false);
+
 
     /**
      * Constructor.
@@ -103,13 +111,13 @@ public abstract class IgfsLocalSecondaryFileSystemDualAbstractSelfTest extends I
     }
 
     /** {@inheritDoc} */
-    @Override protected boolean permissionsSupported() {
-        return false;
+    @Override protected boolean propertiesSupported() {
+        return !U.isWindows() && PROPERTIES_SUPPORT;
     }
 
     /** {@inheritDoc} */
-    @Override protected boolean propertiesSupported() {
-        return false;
+    @Override protected boolean permissionsSupported() {
+        return !U.isWindows();
     }
 
     /** {@inheritDoc} */
@@ -170,6 +178,16 @@ public abstract class IgfsLocalSecondaryFileSystemDualAbstractSelfTest extends I
     }
 
     /**
+     * Test update when parent is the root and the path being updated is missing locally.
+     *
+     * @throws Exception If failed.
+     */
+    public void testUpdateParentRootPathMissing() throws Exception {
+        doUpdateParentRootPathMissing(properties(TEST_GROUP, "0555"));
+    }
+
+
+    /**
      *
      * @throws Exception If failed.
      */

http://git-wip-us.apache.org/repos/asf/ignite/blob/9f211e41/modules/core/src/test/java/org/apache/ignite/internal/processors/igfs/IgfsLocalSecondaryFileSystemProxySelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/igfs/IgfsLocalSecondaryFileSystemProxySelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/igfs/IgfsLocalSecondaryFileSystemProxySelfTest.java
index 848abe2..e7f9bbb 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/igfs/IgfsLocalSecondaryFileSystemProxySelfTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/igfs/IgfsLocalSecondaryFileSystemProxySelfTest.java
@@ -105,11 +105,6 @@ public class IgfsLocalSecondaryFileSystemProxySelfTest extends IgfsProxySelfTest
         return false;
     }
 
-    /** {@inheritDoc} */
-    @Override public void testUpdatePathDoesNotExist() throws Exception {
-        fail("IGNITE-3645");
-    }
-
     /**
      *
      * @throws Exception If failed.

http://git-wip-us.apache.org/repos/asf/ignite/blob/9f211e41/modules/core/src/test/java/org/apache/ignite/internal/processors/igfs/IgfsLocalSecondaryFileSystemTestAdapter.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/igfs/IgfsLocalSecondaryFileSystemTestAdapter.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/igfs/IgfsLocalSecondaryFileSystemTestAdapter.java
index 12714c4..8f6af83 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/igfs/IgfsLocalSecondaryFileSystemTestAdapter.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/igfs/IgfsLocalSecondaryFileSystemTestAdapter.java
@@ -17,6 +17,10 @@
 
 package org.apache.ignite.internal.processors.igfs;
 
+import java.nio.file.attribute.PosixFileAttributeView;
+import java.nio.file.attribute.PosixFileAttributes;
+import java.nio.file.attribute.PosixFilePermission;
+import java.util.HashMap;
 import org.apache.ignite.internal.util.typedef.T2;
 
 import java.io.File;
@@ -77,12 +81,30 @@ public class IgfsLocalSecondaryFileSystemTestAdapter implements IgfsSecondaryFil
 
     /** {@inheritDoc} */
     @Override public Map<String, String> properties(final String path) throws IOException {
-        throw new UnsupportedOperationException("properties");
+        Path p = path(path);
+        PosixFileAttributes attrs = Files.getFileAttributeView(p, PosixFileAttributeView.class).readAttributes();
+
+        Map<String, String> props = new HashMap<>();
+        props.put(IgfsUtils.PROP_USER_NAME, attrs.owner().getName());
+        props.put(IgfsUtils.PROP_GROUP_NAME, attrs.group().getName());
+        props.put(IgfsUtils.PROP_PERMISSION, permissions(path));
+
+        return props;
     }
 
     /** {@inheritDoc} */
     @Override public String permissions(String path) throws IOException {
-        throw new UnsupportedOperationException("permissions");
+        Path p = path(path);
+        PosixFileAttributeView attrView = Files.getFileAttributeView(p, PosixFileAttributeView.class);
+
+        if (attrView == null)
+            throw new UnsupportedOperationException("Posix file attributes not available");
+
+        int perm = 0;
+        for(PosixFilePermission pfp : attrView.readAttributes().permissions())
+            perm |= (1 << 8 - pfp.ordinal());
+
+        return '0' + Integer.toOctalString(perm);
     }
 
     /** {@inheritDoc} */
@@ -123,6 +145,7 @@ public class IgfsLocalSecondaryFileSystemTestAdapter implements IgfsSecondaryFil
      *
      * @param path Path.
      * @throws IOException If failed.
+     * @return {@code true} if the file is deleted successfully. {@code false} otherwise.
      */
     private boolean deleteRecursively(Path path) throws IOException {
         if (Files.isDirectory(path)) {

http://git-wip-us.apache.org/repos/asf/ignite/blob/9f211e41/modules/core/src/test/java/org/apache/ignite/internal/processors/igfs/benchmark/IgfsBenchmark.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/igfs/benchmark/IgfsBenchmark.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/igfs/benchmark/IgfsBenchmark.java
new file mode 100644
index 0000000..9cf6e8f
--- /dev/null
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/igfs/benchmark/IgfsBenchmark.java
@@ -0,0 +1,561 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.processors.igfs.benchmark;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import org.apache.ignite.Ignite;
+import org.apache.ignite.IgniteException;
+import org.apache.ignite.IgniteFileSystem;
+import org.apache.ignite.Ignition;
+import org.apache.ignite.igfs.IgfsFile;
+import org.apache.ignite.igfs.IgfsInputStream;
+import org.apache.ignite.igfs.IgfsOutputStream;
+import org.apache.ignite.igfs.IgfsPath;
+import org.apache.ignite.igfs.IgfsPathNotFoundException;
+
+/**
+ *
+ */
+class FileOperation {
+    /** Buff size. */
+    public static final int BUFF_SIZE = 8192;
+
+    /** Data bufer. */
+    ByteBuffer dataBufer = ByteBuffer.allocate(BUFF_SIZE);
+
+    /** Filesystem. */
+    protected final IgniteFileSystem fs;
+
+    /**
+     * @param fs Ignite filesystem to benchmark.
+     */
+    public FileOperation(IgniteFileSystem fs) {
+        this.fs = fs;
+    }
+
+    /**
+     * @param path Path to do operation.
+     * @throws Exception If failed.
+     */
+    public void handleFile(String path) throws Exception {
+        // No-op.
+    }
+
+    /**
+     * @param path Path to do operation.
+     * @throws Exception If failed.
+     */
+    public void preHandleDir(String path) throws Exception {
+        // No-op.
+    }
+
+    /**
+     * @param path Path to do operation.
+     * @throws Exception If failed.
+     */
+    public void postHandleDir(String path) throws Exception {
+        // No-op.
+    }
+}
+
+/**
+ *
+ */
+class WriteFileOperation extends FileOperation {
+    /** Size. */
+    private int size;
+
+    /**
+     * @param fs Filesystem/
+     * @param size Size to write.
+     */
+    public WriteFileOperation(IgniteFileSystem fs, int size) {
+        super(fs);
+        this.size = size;
+    }
+
+    /** {@inheritDoc} */
+    @Override public void handleFile(String strPath) throws Exception {
+        IgfsPath path = new IgfsPath(strPath);
+        IgfsOutputStream out = null;
+
+        try {
+            out = fs.create(path, false);
+        }
+        catch (IgniteException ex) {
+            System.out.println("create file " + path.toString() + " failed: " + ex);
+            throw ex;
+        }
+
+        try {
+            for (int i = 0; i < size / dataBufer.capacity(); i++)
+                out.write(dataBufer.array());
+        }
+        catch (IOException ex) {
+            System.out.println("write file " + path.toString() + " failed: " + ex);
+            throw ex;
+        }
+        finally {
+            out.close();
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override public void preHandleDir(String strPath) throws Exception {
+        IgfsPath path = new IgfsPath(strPath);
+
+        if (fs.exists(path))
+            throw new IgniteException("path " + path.toString() + " already exists");
+
+        try {
+            fs.mkdirs(path);
+        }
+        catch (IgniteException ex) {
+            throw ex;
+        }
+    }
+}
+
+/**
+ *
+ */
+class ReadFileOperation extends FileOperation {
+    /** Size. */
+    private int size;
+
+    /**
+     * @param fs Filesystem
+     * @param size Size to read.
+     */
+    public ReadFileOperation(IgniteFileSystem fs, int size) {
+        super(fs);
+        this.size = size;
+    }
+
+    /** {@inheritDoc} */
+    @Override public void handleFile(String strPath) throws Exception {
+        IgfsPath path = new IgfsPath(strPath);
+        IgfsInputStream in = null;
+
+        try {
+            in = fs.open(path);
+        }
+        catch (IgfsPathNotFoundException ex) {
+            System.out.println("file " + path.toString() + " not exist: " + ex);
+            throw ex;
+        }
+        catch (IgniteException ex) {
+            System.out.println("open file " + path.toString() + " failed: " + ex);
+            throw ex;
+        }
+
+        try {
+            for (int i = 0; i < size / dataBufer.capacity(); i++)
+                in.read(dataBufer.array());
+        }
+        catch (IOException ex) {
+            System.out.println("read file " + path.toString() + " failed: " + ex);
+            throw ex;
+        }
+        finally {
+            in.close();
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override public void preHandleDir(String strPath) throws Exception {
+        IgfsPath path = new IgfsPath(strPath);
+
+        if (!fs.exists(path)) {
+            System.out.println("path " + path.toString() + " not exist");
+            throw new IgniteException("path " + path.toString() + " not exist");
+        }
+    }
+}
+
+/**
+ *
+ */
+class DeleteFileOperation extends FileOperation {
+    /** Size. */
+    private int size;
+
+    /**
+     * @param fs Filesystem.
+     * @param size Size.
+     */
+    public DeleteFileOperation(IgniteFileSystem fs, int size) {
+        super(fs);
+        this.size = size;
+    }
+
+    /** {@inheritDoc} */
+    @Override public void handleFile(String strPath) throws Exception {
+        IgfsPath path = new IgfsPath(strPath);
+        fs.delete(path, false);
+    }
+
+    /** {@inheritDoc} */
+    @Override public void postHandleDir(String strPath) throws Exception {
+        IgfsPath path = new IgfsPath(strPath);
+        fs.delete(path, false);
+    }
+}
+
+/**
+ *
+ */
+class InfoFileOperation extends FileOperation {
+    /**
+     * @param fs Filesystem.
+     */
+    public InfoFileOperation(IgniteFileSystem fs) {
+        super(fs);
+    }
+
+    /** {@inheritDoc} */
+    @Override public void handleFile(String strPath) throws Exception {
+        IgfsPath path = new IgfsPath(strPath);
+        IgfsFile info = fs.info(path);
+
+        assert info != null : "Info must be not null for exists file. All files must be exists for benchmark";
+    }
+
+    /** {@inheritDoc} */
+    @Override public void postHandleDir(String strPath) throws Exception {
+        IgfsPath path = new IgfsPath(strPath);
+        IgfsFile info = fs.info(path);
+
+        assert info != null : "Info must be not null for exists dir. All dirs must be exists for benchmark";
+    }
+}
+
+/**
+ *
+ */
+class ListPathFileOperation extends FileOperation {
+    /**
+     * @param fs Filesystem.
+     */
+    public ListPathFileOperation(IgniteFileSystem fs) {
+        super(fs);
+    }
+
+    /** {@inheritDoc} */
+    @Override public void postHandleDir(String strPath) throws Exception {
+        IgfsPath path = new IgfsPath(strPath);
+
+        Collection<IgfsPath> lst = fs.listPaths(path);
+
+        assert lst != null : "List of paths must not be null";
+    }
+}
+
+/**
+ *
+ */
+public class IgfsBenchmark {
+    /** Path. */
+    private final String path;
+
+    /** Depth. */
+    private final int depth;
+
+    /** Width. */
+    private final int subDirsCount;
+
+    /** Count. */
+    private final int filesCount;
+
+    /** Size. */
+    private final int size;
+
+    /**
+     * @param path Root test path.
+     * @param depth Directory depth.
+     * @param subDirsCount Count of subdirectories.
+     * @param filesCount Count of files.
+     * @param size Size of file.
+     */
+    public IgfsBenchmark(String path,
+        int depth,
+        int subDirsCount,
+        int filesCount,
+        int size) {
+        this.path = path;
+        this.depth = depth;
+        this.subDirsCount = subDirsCount;
+        this.filesCount = filesCount;
+        this.size = (size > FileOperation.BUFF_SIZE) ? size : FileOperation.BUFF_SIZE;
+    }
+
+    /**
+     * @param lst List of measurement results.
+     * @return Average value.
+     */
+    public static long avg(List<Long> lst) {
+        if (lst.isEmpty())
+            throw new IllegalArgumentException("List must be not empty");
+
+        long sum = 0;
+        for (long l : lst)
+            sum += l;
+
+        return sum / lst.size();
+    }
+
+    /**
+     * @param lst List of measurement results.
+     * @param avg Average value.
+     * @return THe value of the standard derivation.
+     */
+    public static long stdDev(List<Long> lst, long avg) {
+        if (lst.isEmpty())
+            throw new IllegalArgumentException("List must be not empty");
+
+        long sum = 0;
+        for (long l : lst)
+            sum += (l - avg) * (l - avg);
+
+        return (long)Math.sqrt((double)sum / (double)lst.size());
+    }
+
+    /**
+     * @param args Commandline arguments
+     */
+    public static void main(String[] args) {
+        Ignition.setClientMode(Boolean.getBoolean("clientMode"));
+
+        Ignite ignite = Ignition.start(System.getProperty("cfg", "default-config.xml"));
+
+        int wormUpCount = Integer.getInteger("wormup", 2);
+        int cycles = Integer.getInteger("cycles", 10);
+
+        final IgfsBenchmark fsTest = new IgfsBenchmark(
+            System.getProperty("testDir", "/test"),
+            Integer.getInteger("depth", 3),
+            Integer.getInteger("subDirs", 10),
+            Integer.getInteger("files", 10),
+            Integer.getInteger("fileSize", 8) * 1024);
+
+        final IgniteFileSystem fs = ignite.fileSystem("igfs");
+
+        try {
+            for (int i = 0; i < wormUpCount; ++i) {
+                System.out.println("Wormup #" + i + " / " + wormUpCount);
+                fsTest.testWriteFile(fs);
+                fsTest.testReadFile(fs);
+                fsTest.testDeleteFile(fs);
+            }
+        }
+        catch (Exception ex) {
+            System.err.println("Wormup error");
+            ex.printStackTrace(System.err);
+            Ignition.stop(false);
+            return;
+        }
+
+        List<Long> writeRes = new ArrayList<>(cycles);
+        List<Long> readRes = new ArrayList<>(cycles);
+        List<Long> infoRes = new ArrayList<>(cycles);
+        List<Long> listRes = new ArrayList<>(cycles);
+        List<Long> delRes = new ArrayList<>(cycles);
+
+        try {
+            for (int i = 0; i < cycles; ++i) {
+                System.out.println("Benchmark cycle #" + i + " / " + cycles);
+
+                writeRes.add(bench(new Runnable() {
+                    @Override public void run() {
+                        fsTest.testWriteFile(fs);
+                    }
+                }));
+
+                readRes.add(bench(new Runnable() {
+                    @Override public void run() {
+                        fsTest.testReadFile(fs);
+                    }
+                }));
+
+                infoRes.add(bench(new Runnable() {
+                    @Override public void run() {
+                        fsTest.testInfoFile(fs);
+                    }
+                }));
+
+                listRes.add(bench(new Runnable() {
+                    @Override public void run() {
+                        fsTest.testListPathFile(fs);
+                    }
+                }));
+
+                delRes.add(bench(new Runnable() {
+                    @Override public void run() {
+                        fsTest.testDeleteFile(fs);
+                    }
+                }));
+            }
+
+            System.out.println("\n");
+            System.out.println("Write " + avg(writeRes) + " +/- " + stdDev(writeRes, avg(writeRes)));
+            System.out.println("Read " + avg(readRes) + " +/- " + stdDev(readRes, avg(readRes)));
+            System.out.println("Info " + avg(infoRes) + " +/- " + stdDev(infoRes, avg(infoRes)));
+            System.out.println("List " + avg(listRes) + " +/- " + stdDev(listRes, avg(listRes)));
+            System.out.println("Delete " + avg(delRes) + " +/- " + stdDev(delRes, avg(delRes)));
+        }
+        catch (Exception ex) {
+            System.err.println("Benchmark error");
+            ex.printStackTrace(System.err);
+        }
+        finally {
+            Ignition.stop(false);
+        }
+    }
+
+    /**
+     * @param parentPath Begin path.
+     * @param depth Current deep.
+     * @return List of subdirs.
+     */
+    private String[] buildPath(String parentPath, int depth) {
+        String curPath[] = new String[subDirsCount];
+
+        for (int i = 1; i <= curPath.length; i++)
+            curPath[i - 1] = parentPath + "/vdb." + depth + "_" + i + ".dir";
+
+        return curPath;
+    }
+
+    /**
+     * @param parentPath Begin path.
+     * @param operation Test operation to do.
+     * @throws Exception If failed.
+     */
+    private void recurseFile(String parentPath, FileOperation operation) throws Exception {
+        for (int i = 1; i <= filesCount; i++) {
+            String filePath = parentPath + "/vdb_f" + String.format("%0" + String.valueOf(this.filesCount).length() + "d", i) + ".file";
+            operation.handleFile(filePath);
+        }
+    }
+
+    /**
+     * @param parentPath Begin path.
+     * @param depth depth of recurse.
+     * @param operation Test operation to do.
+     * @throws Exception If failed.
+     */
+    private void recursePath(String parentPath, int depth, FileOperation operation) throws Exception {
+        if (depth == this.depth + 1)
+            recurseFile(parentPath, operation);
+        else {
+            String curPath[] = buildPath(parentPath, depth);
+
+            for (String path : curPath) {
+                operation.preHandleDir(path);
+                recursePath(path, depth + 1, operation);
+                operation.postHandleDir(path);
+            }
+        }
+    }
+
+    /**
+     * Do read file operations. Files must be exist.
+     *
+     * @param fs Filesystem.
+     */
+    public void testReadFile(IgniteFileSystem fs) {
+        try {
+            recursePath(path, 1, new ReadFileOperation(fs, size));
+        }
+        catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    /**
+     * Do write file operations.
+     *
+     * @param fs Filesystem.
+     */
+    public void testWriteFile(IgniteFileSystem fs) {
+        try {
+            recursePath(path, 1, new WriteFileOperation(fs, size));
+        }
+        catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    /**
+     * Do delete file operations. Files must be exist.
+     *
+     * @param fs Filesystem.
+     */
+    public void testDeleteFile(IgniteFileSystem fs) {
+        try {
+            recursePath(path, 1, new DeleteFileOperation(fs, 0));
+        }
+        catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    /**
+     * Do info file operations. Files must be exist.
+     *
+     * @param fs Filesystem.
+     */
+    public void testInfoFile(IgniteFileSystem fs) {
+        try {
+            recursePath(path, 1, new InfoFileOperation(fs));
+        }
+        catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    /**
+     * Do info file operations. Files must be exist.
+     *
+     * @param fs Filesystem.
+     */
+    public void testListPathFile(IgniteFileSystem fs) {
+        try {
+            recursePath(path, 1, new ListPathFileOperation(fs));
+        }
+        catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    /**
+     * @param r Runnable.
+     * @return Time of execution in millis.
+     */
+    public static long bench(Runnable r) {
+        long t0 = System.currentTimeMillis();
+
+        r.run();
+
+        return System.currentTimeMillis() - t0;
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/9f211e41/modules/hadoop/src/main/java/org/apache/ignite/internal/processors/hadoop/impl/delegate/HadoopIgfsSecondaryFileSystemDelegateImpl.java
----------------------------------------------------------------------
diff --git a/modules/hadoop/src/main/java/org/apache/ignite/internal/processors/hadoop/impl/delegate/HadoopIgfsSecondaryFileSystemDelegateImpl.java b/modules/hadoop/src/main/java/org/apache/ignite/internal/processors/hadoop/impl/delegate/HadoopIgfsSecondaryFileSystemDelegateImpl.java
index fcad674..203965c 100644
--- a/modules/hadoop/src/main/java/org/apache/ignite/internal/processors/hadoop/impl/delegate/HadoopIgfsSecondaryFileSystemDelegateImpl.java
+++ b/modules/hadoop/src/main/java/org/apache/ignite/internal/processors/hadoop/impl/delegate/HadoopIgfsSecondaryFileSystemDelegateImpl.java
@@ -250,8 +250,7 @@ public class HadoopIgfsSecondaryFileSystemDelegateImpl implements HadoopIgfsSeco
     /** {@inheritDoc} */
     @Override public OutputStream create(IgfsPath path, int bufSize, boolean overwrite, int replication,
         long blockSize, @Nullable Map<String, String> props) {
-        HadoopIgfsProperties props0 =
-            new HadoopIgfsProperties(props != null ? props : Collections.<String, String>emptyMap());
+        HadoopIgfsProperties props0 = new HadoopIgfsProperties(props);
 
         try {
             return fileSystemForUser().create(convert(path), props0.permission(), overwrite, bufSize,

http://git-wip-us.apache.org/repos/asf/ignite/blob/9f211e41/modules/hadoop/src/main/java/org/apache/ignite/internal/processors/hadoop/impl/igfs/HadoopIgfsProperties.java
----------------------------------------------------------------------
diff --git a/modules/hadoop/src/main/java/org/apache/ignite/internal/processors/hadoop/impl/igfs/HadoopIgfsProperties.java b/modules/hadoop/src/main/java/org/apache/ignite/internal/processors/hadoop/impl/igfs/HadoopIgfsProperties.java
index 5427bf1..a322a99 100644
--- a/modules/hadoop/src/main/java/org/apache/ignite/internal/processors/hadoop/impl/igfs/HadoopIgfsProperties.java
+++ b/modules/hadoop/src/main/java/org/apache/ignite/internal/processors/hadoop/impl/igfs/HadoopIgfsProperties.java
@@ -43,6 +43,9 @@ public class HadoopIgfsProperties {
      * @throws IgniteException In case of error.
      */
     public HadoopIgfsProperties(Map<String, String> props) throws IgniteException {
+        if (props == null)
+            return;
+
         usrName = props.get(IgfsUtils.PROP_USER_NAME);
         grpName = props.get(IgfsUtils.PROP_GROUP_NAME);
 


Mime
View raw message