diff --git a/libtaskotron/minion.py b/libtaskotron/minion.py
--- a/libtaskotron/minion.py
+++ b/libtaskotron/minion.py
@@ -87,9 +87,8 @@
             if os.path.exists(config_dir):
                 self.ssh.put_dir(config_dir, '/etc/taskotron/')
 
-        # create needed dirs. remove existing content first.
-        self.ssh.cmd('rm -rf %s' % pipes.quote(self.taskdir))
-        self.ssh.mkdir(self.taskdir)
+        # create taskdir, remove the old one first
+        self.ssh.cmd('rm -rf {0} && mkdir -p {0}'.format(pipes.quote(self.taskdir)))
 
         # patch remote libtaskotron if needed (for dev, shouldn't be used in production)
         if self.arg_data['patch'] is not None:
diff --git a/libtaskotron/remote_exec.py b/libtaskotron/remote_exec.py
--- a/libtaskotron/remote_exec.py
+++ b/libtaskotron/remote_exec.py
@@ -182,7 +182,8 @@
         :raise TaskotronRemoteError: If data could not be written
         '''
 
-        if self._remote_file_exists(remote_path) and not overwrite:
+        # keep the conditionals in this order to avoid unnecessary remote calls
+        if not overwrite and self._remote_file_exists(remote_path):
             log.info('Remote path %s already exists, not overwriting.', remote_path)
             return
 
@@ -206,8 +207,8 @@
 
         :raise TaskotronRemoteError: If the file could not be copied
         '''
-
-        if self._remote_file_exists(remote_path) and not overwrite:
+        # keep the conditionals in this order to avoid unnecessary remote calls
+        if not overwrite and self._remote_file_exists(remote_path):
             log.info('Remote path %s already exists, not overwriting.', remote_path)
             return
 
@@ -238,7 +239,7 @@
 
     def _remote_file_exists(self, remote_path):
         try:
-            path_stats = self.sftp.stat(remote_path)
+            path_stats = self.sftp.lstat(remote_path)
             if path_stats is not None:
                 return True
         except IOError:
@@ -248,33 +249,25 @@
 
     def _remote_isdir(self, remote_path):
         try:
-            return S_ISDIR(self.sftp.stat(remote_path).st_mode)
+            return S_ISDIR(self.sftp.lstat(remote_path).st_mode)
         except IOError:
             return False
 
-    def mkdir(self, name, mode=777):
-        '''Create a directory on a remote machine.
-
-        :param str name: A name of the directory
-        :param int mode: Permissions (posix-style, decimal) of the directory,
-                         default is 777
-
-        :raise TaskotronRemoteError: If the directory could not be created
-        '''
-
-        self.cmd('mkdir -p -m %d %s' % (mode, pipes.quote(name)))
 
     def put_dir(self, local_path, remote_path, overwrite=True):
         '''Copy a directory to a remote path.
 
-        :param str remote_path: A path to the remote directory
+        :param str remote_path: A path to the remote directory. This directory will be created, if
+                                its parent exists. Otherwise you need to create the full tree
+                                structure manually beforehand.
         :param str local_path: A path to the local directory
         :param bool overwrite: Whether to overwrite remote path. Default is True.
 
         :raise TaskotronRemoteError: If the directory could not be uploaded
         '''
 
-        if self._remote_file_exists(remote_path) and not overwrite:
+        # keep the conditionals in this order to avoid unnecessary remote calls
+        if not overwrite and self._remote_file_exists(remote_path):
             log.info('Remote path %s already exists, not overwriting.', remote_path)
             return
 
@@ -285,14 +278,13 @@
                                            (local_path, self.username, self.hostname,
                                             remote_path, e.strerror))
 
-        self.mkdir(remote_path)
+        if not self._remote_isdir(remote_path):
+            self.sftp.mkdir(remote_path)
 
         for file_ in files:
             remote_file = os.path.join(remote_path, file_)
             local_file = os.path.join(local_path, file_)
             if os.path.isdir(local_file):
-                if not self._remote_isdir(remote_file):
-                    self.sftp.mkdir(remote_file)
                 self.put_dir(local_file, remote_file)
             else:
                 self.put_file(local_file, remote_file)
diff --git a/testing/test_remote_exec.py b/testing/test_remote_exec.py
--- a/testing/test_remote_exec.py
+++ b/testing/test_remote_exec.py
@@ -11,9 +11,7 @@
 import pytest
 import paramiko
 from munch import Munch
-from dingus import Dingus
 import mock
-import shlex
 
 from libtaskotron import remote_exec
 from libtaskotron.exceptions import TaskotronRemoteError, TaskotronRemoteProcessError
@@ -90,7 +88,7 @@
 
         return None
 
-    def stat(self, path):
+    def lstat(self, path):
         attrs = paramiko.SFTPAttributes()
 
         if path == STUB_DIR:
@@ -262,23 +260,3 @@
         with pytest.raises(TaskotronRemoteProcessError):
             self.remote.install_pkgs(['libtaskotron', 'rpmlint'])
         assert self.remote.cmd.call_count == 2
-
-    def test_mkdir(self):
-        ref_dirname = 'dirname'
-        self.remote.cmd = Dingus()
-        self.remote.mkdir(ref_dirname)
-        assert self.remote.cmd.calls()[0][1][0] == 'mkdir -p -m 777 %s' % ref_dirname
-
-    def test_mkdir_mode(self):
-        ref_dirname = 'dirname'
-        ref_mode = 644
-        self.remote.cmd = Dingus()
-        self.remote.mkdir(ref_dirname, ref_mode)
-        assert self.remote.cmd.calls()[0][1][0] == 'mkdir -p -m %d %s' % (ref_mode, ref_dirname)
-
-    def test_mkdir_escape(self):
-        ref_dirname = 'dirname with spaces & other ch*r*cters; (how sneaky!)'
-        self.remote.cmd = Dingus()
-        self.remote.mkdir(ref_dirname)
-        cmdline = shlex.split(self.remote.cmd.calls()[0][1][0])
-        assert cmdline[-1] == ref_dirname

