Index: kernel/arch/mips32/include/cp0.h
===================================================================
--- kernel/arch/mips32/include/cp0.h	(revision eb277fa715906377ba6a88f956c11a4061d92281)
+++ kernel/arch/mips32/include/cp0.h	(revision 8f29507ffd4561c8a48b0368b7fd1c2b03fe89ca)
@@ -70,5 +70,5 @@
   { \
       uint32_t retval; \
-      asm("mfc0 %0, $" #reg : "=r"(retval)); \
+      asm volatile ("mfc0 %0, $" #reg : "=r"(retval)); \
       return retval; \
   }
@@ -76,5 +76,5 @@
 #define GEN_WRITE_CP0(nm,reg) static inline void cp0_ ##nm##_write(uint32_t val) \
  { \
-    asm("mtc0 %0, $" #reg : : "r"(val) ); \
+    asm volatile ("mtc0 %0, $" #reg : : "r"(val) ); \
  }
 
Index: uspace/app/bdsh/cmds/modules/cp/cp.c
===================================================================
--- uspace/app/bdsh/cmds/modules/cp/cp.c	(revision eb277fa715906377ba6a88f956c11a4061d92281)
+++ uspace/app/bdsh/cmds/modules/cp/cp.c	(revision 8f29507ffd4561c8a48b0368b7fd1c2b03fe89ca)
@@ -108,4 +108,5 @@
 	for (;;) {
 		ssize_t res;
+		size_t written = 0;
 
 		bytes = read(fd1, buff, blen);
@@ -120,7 +121,8 @@
 			 * returned less data than requested.
 			 */
-			bytes = write(fd2, buff, res);
+			bytes = write(fd2, buff + written, res);
 			if (bytes < 0)
 				goto err;
+			written += bytes;
 			res -= bytes;
 		} while (res > 0);
Index: uspace/app/bdsh/cmds/modules/rm/rm.c
===================================================================
--- uspace/app/bdsh/cmds/modules/rm/rm.c	(revision eb277fa715906377ba6a88f956c11a4061d92281)
+++ uspace/app/bdsh/cmds/modules/rm/rm.c	(revision 8f29507ffd4561c8a48b0368b7fd1c2b03fe89ca)
@@ -101,7 +101,42 @@
 }
 
+static unsigned int rm_recursive_not_empty_dirs(const char *path)
+{
+	DIR *dirp;
+	struct dirent *dp;
+	char buff[PATH_MAX];
+	unsigned int scope;
+	unsigned int ret = 0;
+
+	dirp = opendir(path);
+	if (!dirp) {
+		/* May have been deleted between scoping it and opening it */
+		cli_error(CL_EFAIL, "Could not open %s", path);
+		return ret;
+	}
+
+	memset(buff, 0, sizeof(buff));
+	while ((dp = readdir(dirp))) {
+		snprintf(buff, PATH_MAX - 1, "%s/%s", path, dp->d_name);
+		scope = rm_scope(buff);
+		switch (scope) {
+		case RM_BOGUS:
+			break;
+		case RM_FILE:
+			ret += rm_single(buff);
+			break;
+		case RM_DIR:
+			ret += rm_recursive(buff);
+			break;
+		}
+	}
+	
+	return ret;
+}
+
 static unsigned int rm_recursive(const char *path)
 {
 	int rc;
+	unsigned int ret = 0;
 
 	/* First see if it will just go away */
@@ -111,7 +146,14 @@
 
 	/* Its not empty, recursively scan it */
-	cli_error(CL_ENOTSUP,
-		"Can not remove %s, directory not empty", path);
-	return 1;
+	ret = rm_recursive_not_empty_dirs(path);
+
+	/* Delete directory */
+	rc = rmdir(path);
+	if (rc == 0)
+		return ret;
+
+	cli_error(CL_ENOTSUP, "Can not remove %s", path);
+
+	return ret + 1;
 }
 
Index: uspace/srv/vfs/vfs_ops.c
===================================================================
--- uspace/srv/vfs/vfs_ops.c	(revision eb277fa715906377ba6a88f956c11a4061d92281)
+++ uspace/srv/vfs/vfs_ops.c	(revision 8f29507ffd4561c8a48b0368b7fd1c2b03fe89ca)
@@ -1234,4 +1234,5 @@
 	if (!parentc) {
 		fibril_rwlock_write_unlock(&namespace_rwlock);
+		vfs_node_put(old_node);
 		async_answer_0(rid, rc);
 		free(old);
@@ -1251,4 +1252,5 @@
 	if (rc != EOK) {
 		fibril_rwlock_write_unlock(&namespace_rwlock);
+		vfs_node_put(old_node);
 		async_answer_0(rid, rc);
 		free(old);
@@ -1261,4 +1263,5 @@
 	    (old_node->devmap_handle != new_par_lr.triplet.devmap_handle)) {
 		fibril_rwlock_write_unlock(&namespace_rwlock);
+		vfs_node_put(old_node);
 		async_answer_0(rid, EXDEV);	/* different file systems */
 		free(old);
@@ -1279,4 +1282,5 @@
 		if (!new_node) {
 			fibril_rwlock_write_unlock(&namespace_rwlock);
+			vfs_node_put(old_node);
 			async_answer_0(rid, ENOMEM);
 			free(old);
@@ -1290,4 +1294,5 @@
 	default:
 		fibril_rwlock_write_unlock(&namespace_rwlock);
+		vfs_node_put(old_node);
 		async_answer_0(rid, ENOTEMPTY);
 		free(old);
@@ -1300,4 +1305,5 @@
 	if (rc != EOK) {
 		fibril_rwlock_write_unlock(&namespace_rwlock);
+		vfs_node_put(old_node);
 		if (new_node)
 			vfs_node_put(new_node);
