aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/dev.c
diff options
context:
space:
mode:
authorMiklos Szeredi <miklos@szeredi.hu>2003-09-08 11:14:11 +0000
committerMiklos Szeredi <miklos@szeredi.hu>2003-09-08 11:14:11 +0000
commitda4e486a8ec9ad172eb7834a973a14004170ec14 (patch)
treea32078a31cf55bf9dac48a0e4694ff6993aa4495 /kernel/dev.c
parent868f16fa2462d744127803dcb57fa8cfcbe1584d (diff)
downloadlibfuse-da4e486a8ec9ad172eb7834a973a14004170ec14.tar.gz
caching patch by Michael Grigoriev
Diffstat (limited to 'kernel/dev.c')
-rw-r--r--kernel/dev.c53
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