]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - fs/fuse/dev.c
fuse: implement unsolicited notification
[linux-2.6-omap-h63xx.git] / fs / fuse / dev.c
index 225388f54ae72c92c3b6af528210c7103414a63e..ffd670bb8c8c540b735a4353a8bb07453c797f1d 100644 (file)
@@ -816,6 +816,15 @@ static ssize_t fuse_dev_read(struct kiocb *iocb, const struct iovec *iov,
        return err;
 }
 
+static int fuse_notify(struct fuse_conn *fc, enum fuse_notify_code code,
+                      unsigned int size, struct fuse_copy_state *cs)
+{
+       switch (code) {
+       default:
+               return -EINVAL;
+       }
+}
+
 /* Look up request on processing list by unique ID */
 static struct fuse_req *request_find(struct fuse_conn *fc, u64 unique)
 {
@@ -879,9 +888,23 @@ static ssize_t fuse_dev_write(struct kiocb *iocb, const struct iovec *iov,
        err = fuse_copy_one(&cs, &oh, sizeof(oh));
        if (err)
                goto err_finish;
+
+       err = -EINVAL;
+       if (oh.len != nbytes)
+               goto err_finish;
+
+       /*
+        * Zero oh.unique indicates unsolicited notification message
+        * and error contains notification code.
+        */
+       if (!oh.unique) {
+               err = fuse_notify(fc, oh.error, nbytes - sizeof(oh), &cs);
+               fuse_copy_finish(&cs);
+               return err ? err : nbytes;
+       }
+
        err = -EINVAL;
-       if (!oh.unique || oh.error <= -1000 || oh.error > 0 ||
-           oh.len != nbytes)
+       if (oh.error <= -1000 || oh.error > 0)
                goto err_finish;
 
        spin_lock(&fc->lock);