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
> *
> * 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';
>