Overlay filesystem

From: Pavel Machek (pavel@suse.cz)
Date: Wed Apr 19 2000 - 06:03:15 EST


Hi!

In 2.3.99-pre3 and less, I had patch which redirected all accesses to
nonexistant files into /overlay filesystem. It is handy for stuff like
transparent decompression of .gz files or entering of .tar.gz archives
with simple cd.

Question is: is there simple way to do this with "new" vfs, or should
I just try to redo stuff I did for 2.3.99-pre3?

                                                                Pavel

Old patch looked like this:

--- clean/fs/namei.c Sat Mar 18 20:31:57 2000
+++ linux/fs/namei.c Wed Apr 12 22:30:27 2000
@@ -29,7 +29,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])
@@ -314,6 +314,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.
  *
@@ -381,6 +413,7 @@
                                 flags |= LOOKUP_CONTINUE;
                 }
 
+//printk( "(L: %s, %d)", this.name, follow );
                 /*
                  * See if the low-level filesystem might want
                  * to use its own hash..
@@ -391,7 +424,7 @@
                         if (error < 0) {
                                 dentry = ERR_PTR(error);
                                 break;
- }
+ }
                 }
 
                 /* This does the actual lookups.. */
@@ -407,6 +440,58 @@
                         /* Check mountpoints.. */
                         dentry = follow_mount(dentry);
                 }
+#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, flags);
+ if (!tdentry) {
+ tdentry = real_lookup(tbase, &this, flags);
+ 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;
 
                 base = do_follow_link(base, dentry, flags);
                 if (IS_ERR(base))

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



This archive was generated by hypermail 2b29 : Sun Apr 23 2000 - 21:00:14 EST