diff options
-rw-r--r-- | fs/fuse/dev.c | 27 | ||||
-rw-r--r-- | include/linux/fuse.h | 4 |
2 files changed, 29 insertions, 2 deletions
diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c index 225388f54ae7..ffd670bb8c8c 100644 --- a/fs/fuse/dev.c +++ b/fs/fuse/dev.c | |||
@@ -816,6 +816,15 @@ static ssize_t fuse_dev_read(struct kiocb *iocb, const struct iovec *iov, | |||
816 | return err; | 816 | return err; |
817 | } | 817 | } |
818 | 818 | ||
819 | static int fuse_notify(struct fuse_conn *fc, enum fuse_notify_code code, | ||
820 | unsigned int size, struct fuse_copy_state *cs) | ||
821 | { | ||
822 | switch (code) { | ||
823 | default: | ||
824 | return -EINVAL; | ||
825 | } | ||
826 | } | ||
827 | |||
819 | /* Look up request on processing list by unique ID */ | 828 | /* Look up request on processing list by unique ID */ |
820 | static struct fuse_req *request_find(struct fuse_conn *fc, u64 unique) | 829 | static struct fuse_req *request_find(struct fuse_conn *fc, u64 unique) |
821 | { | 830 | { |
@@ -879,9 +888,23 @@ static ssize_t fuse_dev_write(struct kiocb *iocb, const struct iovec *iov, | |||
879 | err = fuse_copy_one(&cs, &oh, sizeof(oh)); | 888 | err = fuse_copy_one(&cs, &oh, sizeof(oh)); |
880 | if (err) | 889 | if (err) |
881 | goto err_finish; | 890 | goto err_finish; |
891 | |||
892 | err = -EINVAL; | ||
893 | if (oh.len != nbytes) | ||
894 | goto err_finish; | ||
895 | |||
896 | /* | ||
897 | * Zero oh.unique indicates unsolicited notification message | ||
898 | * and error contains notification code. | ||
899 | */ | ||
900 | if (!oh.unique) { | ||
901 | err = fuse_notify(fc, oh.error, nbytes - sizeof(oh), &cs); | ||
902 | fuse_copy_finish(&cs); | ||
903 | return err ? err : nbytes; | ||
904 | } | ||
905 | |||
882 | err = -EINVAL; | 906 | err = -EINVAL; |
883 | if (!oh.unique || oh.error <= -1000 || oh.error > 0 || | 907 | if (oh.error <= -1000 || oh.error > 0) |
884 | oh.len != nbytes) | ||
885 | goto err_finish; | 908 | goto err_finish; |
886 | 909 | ||
887 | spin_lock(&fc->lock); | 910 | spin_lock(&fc->lock); |
diff --git a/include/linux/fuse.h b/include/linux/fuse.h index 608e300ae883..abde9949e2c0 100644 --- a/include/linux/fuse.h +++ b/include/linux/fuse.h | |||
@@ -203,6 +203,10 @@ enum fuse_opcode { | |||
203 | FUSE_IOCTL = 39, | 203 | FUSE_IOCTL = 39, |
204 | }; | 204 | }; |
205 | 205 | ||
206 | enum fuse_notify_code { | ||
207 | FUSE_NOTIFY_CODE_MAX, | ||
208 | }; | ||
209 | |||
206 | /* The read buffer is required to be at least 8k, but may be much larger */ | 210 | /* The read buffer is required to be at least 8k, but may be much larger */ |
207 | #define FUSE_MIN_READ_BUFFER 8192 | 211 | #define FUSE_MIN_READ_BUFFER 8192 |
208 | 212 | ||