[patch] Re: union mount - general questions

Pavel Machek (pavel@suse.cz)
Sun, 21 Nov 1999 00:11:24 +0100


Hi!

> > 1. Is it (...or will it;) be possible to merge different types of
> > file-systems (eg. mount an ext2 fs rw over a ro mounted minix
> > partition)?
> > 2. Hopefully union mounts will be able through loop devices? I'd love
> > to use this with CD images which contain backups...
>
> Answer to both questions: if you write the patch, you get to decide!
> Since it hasn't been written yet, nobody can say more....

It was not written? And what is this?

I'll tell you. It is union mount of / and /overlay onto /. Good luck
with it.

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;
}
+

-- 
I'm really pavel@ucw.cz. Look at http://195.113.31.123/~pavel.  Pavel
Hi! I'm a .signature virus! Copy me into your ~/.signature, please!

- 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/