diff options
-rw-r--r-- | src/findbranch.c | 18 | ||||
-rw-r--r-- | src/findbranch.h | 1 | ||||
-rw-r--r-- | src/unionfs.c | 5 |
3 files changed, 20 insertions, 4 deletions
diff --git a/src/findbranch.c b/src/findbranch.c index 145edf6..9581c3a 100644 --- a/src/findbranch.c +++ b/src/findbranch.c @@ -107,8 +107,10 @@ int find_rorw_branch(const char *path) { /** * Find a writable branch. If file does not exist, we check for * the parent directory. + * @path - the path to find or to copy (with last element cut off) + * @ rw_hint - the rw branch to copy to, set to -1 to autodetect it */ -int find_rw_branch_cutlast(const char *path) { +int __find_rw_branch_cutlast(const char *path, int rw_hint) { DBG_IN(); int branch = find_rw_branch_cow(path); @@ -136,8 +138,12 @@ int find_rw_branch_cutlast(const char *path) { goto out; } + int branch_rw; // since it is a directory, any rw-branch is fine - int branch_rw = find_lowest_rw_branch(uopt.nbranches); + if (rw_hint == -1) + branch_rw = find_lowest_rw_branch(uopt.nbranches); + else + branch_rw = rw_hint; // no writable branch found, we must return an error if (branch_rw < 0) { @@ -155,6 +161,14 @@ out: } /** + * Call __find_rw_branch_cutlast() + */ +int find_rw_branch_cutlast(const char *path) { + int rw_hint = -1; // autodetect rw_branch + return __find_rw_branch_cutlast(path, rw_hint); +} + +/** * copy-on-write * Find path in a union branch and if this branch is read-only, * copy the file to a read-write branch. diff --git a/src/findbranch.h b/src/findbranch.h index 6378d86..56cfc08 100644 --- a/src/findbranch.h +++ b/src/findbranch.h @@ -15,6 +15,7 @@ typedef enum searchflag { int find_rorw_branch(const char *path); 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); #endif diff --git a/src/unionfs.c b/src/unionfs.c index cd58a83..091f00d 100644 --- a/src/unionfs.c +++ b/src/unionfs.c @@ -241,10 +241,11 @@ static int unionfs_link(const char *from, const char *to) { int i = find_rw_branch_cow(from); if (i == -1) return -errno; - // FIXME, we actually MUST COW to i - int j = find_rw_branch_cutlast(to); + int j = __find_rw_branch_cutlast(to, i); if (j == -1) return -errno; + DBG("from branch: %d to branch: %d\n", i, j); + char f[PATHLEN_MAX], t[PATHLEN_MAX]; if (BUILD_PATH(f, uopt.branches[i].path, from)) return -ENAMETOOLONG; if (BUILD_PATH(t, uopt.branches[j].path, to)) return -ENAMETOOLONG; |