diff options
author | Miklos Szeredi <miklos@szeredi.hu> | 2003-09-08 11:14:11 +0000 |
---|---|---|
committer | Miklos Szeredi <miklos@szeredi.hu> | 2003-09-08 11:14:11 +0000 |
commit | da4e486a8ec9ad172eb7834a973a14004170ec14 (patch) | |
tree | a32078a31cf55bf9dac48a0e4694ff6993aa4495 /kernel/dev.c | |
parent | 868f16fa2462d744127803dcb57fa8cfcbe1584d (diff) | |
download | libfuse-da4e486a8ec9ad172eb7834a973a14004170ec14.tar.gz |
caching patch by Michael Grigoriev
Diffstat (limited to 'kernel/dev.c')
-rw-r--r-- | kernel/dev.c | 53 |
1 files changed, 48 insertions, 5 deletions
diff --git a/kernel/dev.c b/kernel/dev.c index e703b11..cdc4b6c 100644 --- a/kernel/dev.c +++ b/kernel/dev.c @@ -359,14 +359,46 @@ static inline int copy_out_header(struct fuse_out_header *oh, const char *buf, 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) { @@ -381,7 +413,17 @@ static ssize_t fuse_dev_write(struct file *file, const char *buf, 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) { @@ -408,6 +450,7 @@ static ssize_t fuse_dev_write(struct file *file, const char *buf, wake_up(&req->waitq); spin_unlock(&fuse_lock); + out: if(!err) return nbytes; else |