Hi Jan,
I analyzed your patch. I don't think that is Ok for my purpose because
the writing branch is fixed just at the creation time of the union.
In any case, thanks a lot for your patience to reply me.
ciao
luigi
Jan Engelhardt ha scritto:
Index: linux-2.6.18_rc4/fs/unionfs/inode.c
===
--- linux-2.6.18_rc4.orig/fs/unionfs/inode.c
+++ linux-2.6.18_rc4/fs/unionfs/inode.c
@@ -10,6 +10,7 @@
* Copyright (c) 2003 Harikesavan Krishnan
* Copyright (c) 2003-2006 Stony Brook University
* Copyright (c) 2003-2006 The Research Foundation of State University of
New York
+ * Copyright © 2005-2006 Jan Engelhardt jengelh [at] gmx de
*
* For specific licensing information, see the COPYING file distributed with
* this package.
@@ -30,6 +31,84 @@ extern int unionfs_readlink(struct dentr
extern void unionfs_put_link(struct dentry *dentry, struct nameidata *nd,
void *cookie);
+static int branch_wmaxspc(struct super_block *);
+static void branch_move(struct super_block *, int);
+
+//-
+static int branch_wmaxspc(struct super_block *sb) {
+// Returns the number of the read-write branch with the most free space
+int bstart = sbstart(sb), bend = sbmax(sb), bindex;
+struct super_block *hidden_sb;
+struct kstatfs statbuf = {};
+sector_t best_free = 0;
+int best_branch= 0;
+
+for(bindex = bstart; bindex bend; ++bindex) {
+int bindex1, sb_dup = 0;
+
+if(!(branchperms(sb, bindex) MAY_WRITE))
+continue;
+
+hidden_sb = stohs_index(sb, bindex);
+for(bindex1 = bstart; bindex1 bindex; ++bindex1) {
+if(hidden_sb == stohs_index(sb, bindex1)) {
+sb_dup = 1;
+break;
+}
+}
+if(sb_dup || vfs_statfs(hidden_sb-s_root, statbuf) != 0)
+continue;
+if(statbuf.f_bfree best_free) {
+best_free = statbuf.f_bfree;
+best_branch = bindex;
+}
+}
+
+return best_branch;
+}
+
+static void branch_move(struct super_block *sb, int chosen) {
+// Move the CHOSEN branch into first place
+struct dentry *hdentry, *sroot = sb-s_root;
+struct inode *hinode, *sinode = sroot-d_inode;
+struct super_block *hsb;
+struct vfsmount *hmount;
+int count, perms, gen, i;
+
+lock_super(sb);
+atomic_inc(stopd(sb)-usi_generation);
+gen = atomic_read(stopd(sb)-usi_generation);
+atomic_set(dtopd(sroot)-udi_generation, gen);
+atomic_set(itopd(sinode)-uii_generation, gen);
+
+count = branch_count(sb, chosen);
+perms = branchperms(sb, chosen);
+hmount = stohiddenmnt_index(sb, chosen);
+hsb = stohs_index(sb, chosen);
+hdentry = dtohd_index(sroot, chosen);
+hinode = itohi_index(sinode, chosen);
+
+for(i = chosen; i 0; --i) {
+int prev = i - 1;
+set_branch_count(sb, i, branch_count(sb, prev));
+set_branchperms(sb, i, branchperms(sb, prev));
+set_stohiddenmnt_index(sb, i, stohiddenmnt_index(sb, prev));
+set_stohs_index(sb, i, stohs_index(sb, prev));
+set_dtohd_index(sroot, i, dtohd_index(sroot, prev));
+set_itohi_index(sinode, i, itohi_index(sinode, prev));
+}
+
+set_branch_count(sb, 0, count);
+set_branchperms(sb, 0, perms);
+set_stohiddenmnt_index(sb, 0, hmount);
+set_stohs_index(sb, 0, hsb);
+set_dtohd_index(sroot, 0, hdentry);
+set_itohi_index(sinode, 0, hinode);
+
+unlock_super(sb);
+return;
+}
+
static int unionfs_create(struct inode *parent, struct dentry *dentry,
int mode, struct nameidata *nd)
{
@@ -38,13 +117,17 @@ static int unionfs_create(struct inode *
struct dentry *whiteout_dentry = NULL;
struct dentry *new_hidden_dentry;
struct dentry *hidden_parent_dentry = NULL;
- int bindex = 0, bstart;
+ int bindex = 0, bstart, mx;
char *name = NULL;
print_entry_location();
lock_dentry(dentry);
print_dentry(IN unionfs_create, dentry);
+if(stopd(dentry-d_sb)-usi_spread
+ (mx = branch_wmaxspc(dentry-d_sb)) != 0)
+branch_move(dentry-d_sb, mx);
+
/* We start out in the leftmost branch. */
bstart = dbstart(dentry);
hidden_dentry = dtohd(dentry);
Index: linux-2.6.18_rc4/fs/unionfs/main.c
===
--- linux-2.6.18_rc4.orig/fs/unionfs/main.c
+++ linux-2.6.18_rc4/fs/unionfs/main.c
@@ -487,6 +487,11 @@ static struct unionfs_dentry_info *union
*optarg++ = '\0';
}
+if(strcmp(optname, spread) == 0) {
+stopd(sb)-usi_spread = 1;
+