[PATCH] Re: cachefs module for linux?

Pavel Machek (pavel@bug.ucw.cz)
Thu, 10 Jun 1999 23:10:59 +0200


Hi!

> > Anyway, going back to CacheFS, obviously some people would like to have such a
> > thing, but obviously also, none of them needs it badly enough that she's
> > willing to write it... so the discussion is mostly pointless.

Well, I don't think so.

> Usage -- In the generic VFS routines, add a check upon file open() to
> see if it is backed by a local CacheFS cache. This could be a flag set
> in the superblock.

This means you can not cache parts of files. Which may or may not hurt.

> When each file read occurs, if the cached flag is set on that inode,
> then try to read from the local CacheFS. If the read fails, or the file
> is not cached, normal file read occurs.
>
> Adding hooks in the generic VFS should make it possible to cache any
> filesystem easily.

Take a look at this patch:

If you mount all your filesystems into /overlay tree, then / tree will
serve as cache. This might also work for people wanting to override
CDs.

Problem is with writes - how it is done now, they will go into /
filesystem so you'll not be able to modify cached fs... Which might be
considered feature. (Be sure to define symbol CLEAN.)

Pavel

--- clean//fs/namei.c Tue May 25 00:16:04 1999
+++ linux/fs/namei.c Tue May 18 11:12:41 1999
@@ -10,6 +10,8 @@

/* [Feb 1997 T. Schoebel-Theuer] Complete rewrite of the pathname
* lookup logic.
+ *
+ * 1998-1999 Pavel Machek - /overlay hack (thanks to mikulas for correcting bugs in it)
*/

#include <linux/mm.h>
@@ -27,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])
@@ -297,6 +299,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.
*
@@ -364,6 +398,7 @@
flags |= LOOKUP_CONTINUE;
}

+//printk( "(L: %s, %d)", this.name, follow );
/*
* See if the low-level filesystem might want
* to use its own hash..
@@ -374,7 +409,7 @@
if (error < 0) {
dentry = ERR_PTR(error);
break;
- }
+ }
}

/* This does the actual lookups.. */
@@ -387,6 +422,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, 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;

/* Check mountpoints.. */
dentry = follow_mount(dentry);
@@ -1404,3 +1491,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/