Index: uspace/app/bdsh/cmds/builtins/cd/cd.c
===================================================================
--- uspace/app/bdsh/cmds/builtins/cd/cd.c	(revision f2b3d3ea3dc1fbb7a2312b326613bcc88a3bfaf5)
+++ uspace/app/bdsh/cmds/builtins/cd/cd.c	(revision 35a3565109a7247b385218f58b83312d3c235a59)
@@ -41,4 +41,29 @@
 static const char *cmdname = "cd";
 
+/* Previous directory variables.
+ *
+ * Declaring them static to avoid many "== NULL" checks.
+ * PATH_MAX is not that big to cause any problems with memory overhead.
+ */
+static char previous_directory[PATH_MAX] = "";
+static char previous_directory_tmp[PATH_MAX];
+static bool previous_directory_valid = true;
+static bool previous_directory_set = false;
+
+static int chdir_and_remember(const char *new_dir) {
+
+	char *ok = getcwd(previous_directory_tmp, PATH_MAX);
+	previous_directory_valid = ok != NULL;
+	previous_directory_set = true;
+
+	int rc = chdir(new_dir);
+	if (rc != EOK) {
+		return rc;
+	}
+
+	str_cpy(previous_directory, PATH_MAX, previous_directory_tmp);
+	return EOK;
+}
+
 void help_cmd_cd(unsigned int level)
 {
@@ -55,4 +80,5 @@
 }
 
+
 /* This is a very rudamentary 'cd' command. It is not 'link smart' (yet) */
 
@@ -65,8 +91,10 @@
 	/* Handle cd -- -. Override to switch to a directory named '-' */
 	bool hyphen_override = false;
+	char *target_directory = argv[1];
 	if (argc == 3) {
-		if(!str_cmp(argv[1], "--")) {
+		if (!str_cmp(argv[1], "--")) {
 			hyphen_override = true;
 			argc--;
+			target_directory = argv[2];
 		}
 	}
@@ -92,27 +120,22 @@
 
 	/* Handle 'cd -' first. */
-	if (!str_cmp(argv[1], "-") && !hyphen_override) {
-		char *buffer = (char *) malloc(PATH_MAX);
-		if (!buffer) {
+	if (!str_cmp(target_directory, "-") && !hyphen_override) {
+		if (!previous_directory_valid) {
+			cli_error(CL_EFAIL, "Cannot switch to previous directory");
+			return CMD_FAILURE;
+		}
+		if (!previous_directory_set) {
+			cli_error(CL_EFAIL, "No previous directory to switch to");
+			return CMD_FAILURE;
+		}
+		char *prev_dup = str_dup(previous_directory);
+		if (prev_dup == NULL) {
 			cli_error(CL_ENOMEM, "Cannot switch to previous directory");
 			return CMD_FAILURE;
 		}
-		memset(buffer, 0, PATH_MAX);
-		getprevwd(buffer, PATH_MAX);
-		if (*buffer == '\0') {
-			cli_error(CL_EFAIL, "No previous directory to switch to");
-			free(buffer);
-			return CMD_FAILURE;
-		} else {
-			rc = chdir(buffer);
-			free(buffer);
-		}
-	} else if (hyphen_override) {
-		/* Handles 'cd -- <dirname>'.
-		 * Override for directory named '-'.
-		 */
-		rc = chdir(argv[2]);
+		rc = chdir_and_remember(prev_dup);
+		free(prev_dup);
 	} else {
-		rc = chdir(argv[1]);
+		rc = chdir_and_remember(target_directory);
 	}
 
@@ -126,8 +149,8 @@
 			break;
 		case ENOENT:
-			cli_error(CL_ENOENT, "Invalid directory `%s'", argv[1]);
+			cli_error(CL_ENOENT, "Invalid directory `%s'", target_directory);
 			break;
 		default:
-			cli_error(CL_EFAIL, "Unable to change to `%s'", argv[1]);
+			cli_error(CL_EFAIL, "Unable to change to `%s'", target_directory);
 			break;
 		}
Index: uspace/lib/c/generic/vfs/vfs.c
===================================================================
--- uspace/lib/c/generic/vfs/vfs.c	(revision f2b3d3ea3dc1fbb7a2312b326613bcc88a3bfaf5)
+++ uspace/lib/c/generic/vfs/vfs.c	(revision 35a3565109a7247b385218f58b83312d3c235a59)
@@ -58,16 +58,9 @@
 static async_sess_t *vfs_sess = NULL;
 
-/* Current (working) directory. */
 static FIBRIL_MUTEX_INITIALIZE(cwd_mutex);
+
 static int cwd_fd = -1;
 static char *cwd_path = NULL;
 static size_t cwd_size = 0;
-
-/* Previous directory. */
-static FIBRIL_MUTEX_INITIALIZE(pwd_mutex);
-static int pwd_fd = -1;
-static char *pwd_path = NULL;
-static size_t pwd_size = 0;
-
 
 /** Start an async exchange on the VFS session.
@@ -758,21 +751,11 @@
 	fibril_mutex_lock(&cwd_mutex);
 	
-
-	fibril_mutex_lock(&pwd_mutex);
-
-	if (pwd_fd >= 0)
-		close(pwd_fd);
-
-
-	if (pwd_path)
-		free(pwd_path);
-
-
-	pwd_fd = cwd_fd;
-	pwd_path = cwd_path;
-	pwd_size = cwd_size;
-
-	fibril_mutex_unlock(&pwd_mutex);
-
+	if (cwd_fd >= 0)
+		close(cwd_fd);
+	
+	
+	if (cwd_path)
+		free(cwd_path);
+	
 	cwd_fd = fd;
 	cwd_path = abs;
@@ -798,23 +781,4 @@
 	fibril_mutex_unlock(&cwd_mutex);
 	
-	return buf;
-}
-
-
-char *getprevwd(char *buf, size_t size)
-{
-	if (size == 0)
-		return NULL;
-
-	fibril_mutex_lock(&pwd_mutex);
-
-	if ((pwd_size == 0) || (size < pwd_size + 1)) {
-		fibril_mutex_unlock(&pwd_mutex);
-		return NULL;
-	}
-
-	str_cpy(buf, size, pwd_path);
-	fibril_mutex_unlock(&pwd_mutex);
-
 	return buf;
 }
Index: uspace/lib/c/include/unistd.h
===================================================================
--- uspace/lib/c/include/unistd.h	(revision f2b3d3ea3dc1fbb7a2312b326613bcc88a3bfaf5)
+++ uspace/lib/c/include/unistd.h	(revision 35a3565109a7247b385218f58b83312d3c235a59)
@@ -74,5 +74,4 @@
 
 extern char *getcwd(char *, size_t);
-extern char *getprevwd(char *, size_t);
 extern int rmdir(const char *);
 extern int chdir(const char *);
