summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRadek Podgorny <radek@podgorny.cz>2015-10-23 11:59:39 +0200
committerRadek Podgorny <radek@podgorny.cz>2015-10-23 11:59:39 +0200
commitd7847ae5e9758a73d8286467c121f5718c4cdd57 (patch)
treeb90d0a17ab6e35741e8dcd83fa0a1a8c6058fbdc
parentd55864e47794ceb960f4b7b4d1ec5f7e205eb5d7 (diff)
downloadunionfs-fuse-git-issue-25.tar.gz
excessive directory copies patch by B Howeissue-25
-rw-r--r--src/cow.c10
-rw-r--r--src/cow.h2
-rw-r--r--src/findbranch.c8
-rw-r--r--src/findbranch.h1
-rw-r--r--src/unionfs.c2
5 files changed, 16 insertions, 7 deletions
diff --git a/src/cow.c b/src/cow.c
index 1e00865..9f2a455 100644
--- a/src/cow.c
+++ b/src/cow.c
@@ -125,7 +125,7 @@ int path_create_cutlast(const char *path, int nbranch_ro, int nbranch_rw) {
/**
* initiate the cow-copy action
*/
-int cow_cp(const char *path, int branch_ro, int branch_rw) {
+int cow_cp(const char *path, int branch_ro, int branch_rw, bool copy_dir) {
DBG("%s\n", path);
// create the path to the file
@@ -160,7 +160,11 @@ int cow_cp(const char *path, int branch_ro, int branch_rw) {
res = copy_link(&cow);
break;
case S_IFDIR:
- res = copy_directory(path, branch_ro, branch_rw);
+ if (copy_dir) {
+ res = copy_directory(path, branch_ro, branch_rw);
+ } else {
+ res = path_create(path, branch_ro, branch_rw);
+ }
break;
case S_IFBLK:
case S_IFCHR:
@@ -207,7 +211,7 @@ int copy_directory(const char *path, int branch_ro, int branch_rw) {
res = 1;
break;
}
- res = cow_cp(member, branch_ro, branch_rw);
+ res = cow_cp(member, branch_ro, branch_rw, true);
if (res != 0) break;
}
diff --git a/src/cow.h b/src/cow.h
index 7410ff2..04d6dfb 100644
--- a/src/cow.h
+++ b/src/cow.h
@@ -9,7 +9,7 @@
#include <sys/stat.h>
-int cow_cp(const char *path, int branch_ro, int branch_rw);
+int cow_cp(const char *path, int branch_ro, int branch_rw, bool copy_dir);
int path_create(const char *path, int nbranch_ro, int nbranch_rw);
int path_create_cutlast(const char *path, int nbranch_ro, int nbranch_rw);
int copy_directory(const char *path, int branch_ro, int branch_rw);
diff --git a/src/findbranch.c b/src/findbranch.c
index 3d0ccf5..5c08563 100644
--- a/src/findbranch.c
+++ b/src/findbranch.c
@@ -179,6 +179,10 @@ int find_rw_branch_cutlast(const char *path) {
RETURN(res);
}
+int find_rw_branch_cow(const char *path) {
+ return find_rw_branch_cow_common(path, false);
+}
+
/**
* copy-on-write
* Find path in a union branch and if this branch is read-only,
@@ -187,7 +191,7 @@ int find_rw_branch_cutlast(const char *path) {
* It will definitely fail, when a ro-branch is on top of a rw-branch
* and a directory is to be copied from ro- to rw-branch.
*/
-int find_rw_branch_cow(const char *path) {
+int find_rw_branch_cow_common(const char *path, bool copy_dir) {
DBG("%s\n", path);
int branch_rorw = find_rorw_branch(path);
@@ -211,7 +215,7 @@ int find_rw_branch_cow(const char *path) {
RETURN(-1);
}
- if (cow_cp(path, branch_rorw, branch_rw)) RETURN(-1);
+ if (cow_cp(path, branch_rorw, branch_rw, copy_dir)) RETURN(-1);
// remove a file that might hide the copied file
remove_hidden(path, branch_rw);
diff --git a/src/findbranch.h b/src/findbranch.h
index 56cfc08..0636285 100644
--- a/src/findbranch.h
+++ b/src/findbranch.h
@@ -17,5 +17,6 @@ int find_lowest_rw_branch(int branch_ro);
int find_rw_branch_cutlast(const char *path);
int __find_rw_branch_cutlast(const char *path, int rw_hint);
int find_rw_branch_cow(const char *path);
+int find_rw_branch_cow_common(const char *path, bool copy_dir);
#endif
diff --git a/src/unionfs.c b/src/unionfs.c
index 69b45e5..91bf6db 100644
--- a/src/unionfs.c
+++ b/src/unionfs.c
@@ -450,7 +450,7 @@ static int unionfs_rename(const char *from, const char *to) {
if (i == -1) RETURN(-errno);
if (!uopt.branches[i].rw) {
- i = find_rw_branch_cow(from);
+ i = find_rw_branch_cow_common(from, true);
if (i == -1) RETURN(-errno);
}