Messages in this thread Patch in this message | | | Date | Thu, 8 Jul 1999 20:56:43 +0200 | From | Pavel Machek <> | Subject | Re: FS union [patch] |
| |
Hi!
> > One possibility that I don't think anyone has mentioned is > > giving the user or programmer finer-grained control over the > > name space for the unioned FS's. In other words, there could > > easily be times when you would want to make just certain files > > in the underlying FS take precedence in the name space. > > One thing that sort of disturbs me ist that you'd really have a whole > filesystem that you'd have to mount and umount every time. I don't know > about POSIX standards etc, but to the layman (me ;) perhaps a kind of > 'extended symlink' would look easier (to use, not necessarily to > implement...) > > Take two directories, say /dir1 and /dir2, create an empty 'union mount > point' (mkdir /union) and join them: > > ln -U /dir1 /dir2 /union > > or perhaps with a different command: > > union /dir1 /dir2 /union > > Then all acesses to /union would get redirected to /dir1, if nothing was > found there, /dir2 would be searched. Write access would go to /dir1 (or > perhaps to somewhere else, whatever). You can, for static content, do this > now with a symlinking script. But not for dynamic content.
I have this working for
ln -U / /overlay /
sense. Patch is here.
Pavel
--- linux-2.2.5.tar.bz2#utar/linux/fs/namei.c Mon Jan 25 06:48:39 1999 +++ linux/fs/namei.c Fri Apr 23 00:12:11 1999 @@ -39,7 +39,7 @@ /* This can be removed after the beta phase. */ #define CACHE_SUPERVISE /* debug the correctness of dcache entries */ -#undef DEBUG /* some other debugging */ +#define DEBUG /* some other debugging */ #define ACC_MODE(x) ("\000\004\002\006"[(x)&O_ACCMODE]) @@ -309,6 +309,38 @@ return dentry; } +struct dentry * +no_file( struct dentry *base, int lookup_flags ) +{ + char *tmp = (char *) __get_free_page(GFP_KERNEL); + char *path = d_path(base, tmp, PAGE_SIZE); + struct dentry *res; + char *s = "yalrevo/"; + + if (strlen(path) > PAGE_SIZE-30) { + /*printk( "Namei: path much too long\n" );*/ + res = ERR_PTR(-ENOENT); + goto done; + } + + if (!strncmp( path, "/overlay", 8 )) { + /*printk( "[loop]" );*/ + res = ERR_PTR(-ENOENT); + goto done; + } + + /*printk( "No file %s / ???...", path );*/ + while (*s) *--path = *s++; + /*printk( "looking %s...", path );*/ + + res = lookup_dentry( path, NULL, lookup_flags ); + /*printk( "done (%x)\n", res );*/ + +done: + free_page((unsigned long) tmp); + return res; +} + /* * Name resolution. * @@ -376,6 +408,7 @@ flags |= LOOKUP_CONTINUE; } +//printk( "(L: %s, %d)", this.name, follow ); /* * See if the low-level filesystem might want * to use its own hash.. @@ -386,7 +419,7 @@ if (error < 0) { dentry = ERR_PTR(error); break; - } + } } /* This does the actual lookups.. */ @@ -399,6 +432,58 @@ break; } } +#ifndef CLEAN + if (strchr( this.name, '#' )) +#endif + if (!dentry->d_inode) { + struct dentry *tbase, *tdentry = NULL; + tbase = no_file( base, lookup_flags ); + if (!IS_ERR(tbase) && (tbase->d_inode)) { + /* We need to do lookup once again. */ + + /* FIXME: We should save original hash... + * [what if fs wanted _normal_ hash?] + * See if the low-level filesystem might want + * to use its own hash.. + */ + if (tbase->d_op && tbase->d_op->d_hash) { + int error; + error = tbase->d_op->d_hash(base, &this); + if (error < 0) { + dentry = ERR_PTR(error); + dput(tbase); + break; + } + } + + /* This does the actual lookups.. */ + tdentry = reserved_lookup(tbase, &this); + if (!tdentry) { + tdentry = cached_lookup(tbase, &this); + if (!tdentry) { + tdentry = real_lookup(tbase, &this); + if (IS_ERR(tdentry)) { + dput(dentry); + dentry = tdentry; + dput(tbase); + break; + } + } + } + if (!IS_ERR(tdentry) && (tdentry->d_inode)) { + dput(dentry); + dput(base); + base = tbase; + dentry = tdentry; + } else { + if (!IS_ERR(tdentry)) dput(tdentry); + dput(tbase); + } + } else if (!IS_ERR(tbase)) dput(tbase); + } + + if (IS_ERR(dentry)) + break; /* Check mountpoints.. */ dentry = follow_mount(dentry); @@ -1329,3 +1414,4 @@ unlock_kernel(); return error; } + -- The best software in life is free (not shareware)! Pavel GCM d? s-: !g p?:+ au- a--@ w+ v- C++@ UL+++ L++ N++ E++ W--- M- Y- R+
- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu Please read the FAQ at http://www.tux.org/lkml/
| |