+2003-09-08 Miklos Szeredi <mszeredi@inf.bme.hu>
+
+ * Integrated caching patch by Michael Grigoriev
+
+2003-09-08 Miklos Szeredi <mszeredi@inf.bme.hu>
+
+ * Added "Filesystems" file with descriptions of projects using
+ FUSE
+
2003-06-02 Miklos Szeredi <mszeredi@inf.bme.hu>
* And another spec-file fix by Achim Settelmeier
--- /dev/null
+Name: OW
+
+Author: Paul H. Alfille <palfille at partners org>
+
+Homepage: http://home.earthlink.net/~palfille/ow.html
+
+Description:
+
+ OWFS is a method under linux to allow 1-wire devices to appear like
+ files in a directory.
+
+==============================================================================
+Name: FunFS
+
+Author: Michael Grigoriev (Net Integration Technologies) <mag at
+luminal org>
+
+Homepage: http://open.nit.ca/wiki/?page=FunFS
+
+Description:
+
+ FunFS is an advanced network file system with a simple goal: to be
+ better than NFS.
+
+==============================================================================
doing the mount will be allowed to access the filesystem */
#define FUSE_ALLOW_OTHER (1 << 1)
+/** If the FUSE_KERNEL_CACHE flag is given, then files will be cached
+ until the INVALIDATE operation is invoked */
+#define FUSE_KERNEL_CACHE (1 << 2)
+
struct fuse_attr {
unsigned int mode;
unsigned int nlink;
enum fuse_opcode {
FUSE_LOOKUP = 1,
- FUSE_FORGET = 2,
+ FUSE_FORGET = 2, /* no reply */
FUSE_GETATTR = 3,
FUSE_SETATTR = 4,
FUSE_READLINK = 5,
FUSE_READ = 15,
FUSE_WRITE = 16,
FUSE_STATFS = 17,
- FUSE_RELEASE = 18
+ FUSE_RELEASE = 18, /* no reply */
+ FUSE_INVALIDATE = 19 /* user initiated */
};
/* Conservative buffer size for the client */
int error;
};
+struct fuse_user_header {
+ int unique; /* zero */
+ enum fuse_opcode opcode;
+ unsigned long ino;
+};
+
struct fuse_dirent {
unsigned long ino;
unsigned short namelen;
if(copy_from_user(oh, buf, sizeof(struct fuse_out_header)))
return -EFAULT;
- if (oh->error <= -512 || oh->error > 0) {
- printk("fuse_dev_write: bad error value\n");
- return -EIO;
- }
+ return 0;
+}
+
+static int fuse_invalidate(struct fuse_conn *fc, struct fuse_user_header *uh)
+{
+ struct inode *inode = iget(fc->sb, uh->ino);
+ if (!inode)
+ return -ENOENT;
+ invalidate_inode_pages(inode);
+ iput(inode);
return 0;
}
+static int fuse_user_request(struct fuse_conn *fc, const char *buf,
+ size_t nbytes)
+{
+ struct fuse_user_header uh;
+ int err;
+
+ if (nbytes < sizeof(struct fuse_user_header)) {
+ printk("fuse_dev_write: write is short\n");
+ return -EIO;
+ }
+
+ if(copy_from_user(&uh, buf, sizeof(struct fuse_out_header)))
+ return -EFAULT;
+
+ switch(uh.opcode) {
+ case FUSE_INVALIDATE:
+ err = fuse_invalidate(fc, &uh);
+ break;
+
+ default:
+ err = -ENOSYS;
+ }
+ return err;
+}
+
+
static ssize_t fuse_dev_write(struct file *file, const char *buf,
size_t nbytes, loff_t *off)
{
err = copy_out_header(&oh, buf, nbytes);
if(err)
return err;
-
+
+ if (!oh.unique) {
+ err = fuse_user_request(fc, buf, nbytes);
+ goto out;
+ }
+
+ if (oh.error <= -512 || oh.error > 0) {
+ printk("fuse_dev_write: bad error value\n");
+ return -EIO;
+ }
+
spin_lock(&fuse_lock);
req = request_find(fc, oh.unique);
if(req != NULL) {
wake_up(&req->waitq);
spin_unlock(&fuse_lock);
+ out:
if(!err)
return nbytes;
else
in.args[0].size = sizeof(inarg);
in.args[0].value = &inarg;
request_send(fc, &in, &out);
- if(!out.h.error)
+ if(!out.h.error && !(fc->flags & FUSE_KERNEL_CACHE))
invalidate_inode_pages(inode);
return out.h.error;
" -h print help\n"
" -u unmount\n"
" -p check default permissions on files\n"
+ " -c cache in kernel space if possible\n"
" -x allow other users to access the files (only for root)\n",
progname);
exit(1);
break;
switch(argv[a][1]) {
+ case 'c':
+ flags |= FUSE_KERNEL_CACHE;
+ break;
+
case 'h':
usage();
break;