diff options
Diffstat (limited to 'fs/fuse/dev.c')
| -rw-r--r-- | fs/fuse/dev.c | 83 |
1 files changed, 82 insertions, 1 deletions
diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c index 8fed2ed12f38..f58ecbc416c8 100644 --- a/fs/fuse/dev.c +++ b/fs/fuse/dev.c | |||
| @@ -849,6 +849,81 @@ err: | |||
| 849 | return err; | 849 | return err; |
| 850 | } | 850 | } |
| 851 | 851 | ||
| 852 | static int fuse_notify_inval_inode(struct fuse_conn *fc, unsigned int size, | ||
| 853 | struct fuse_copy_state *cs) | ||
| 854 | { | ||
| 855 | struct fuse_notify_inval_inode_out outarg; | ||
| 856 | int err = -EINVAL; | ||
| 857 | |||
| 858 | if (size != sizeof(outarg)) | ||
| 859 | goto err; | ||
| 860 | |||
| 861 | err = fuse_copy_one(cs, &outarg, sizeof(outarg)); | ||
| 862 | if (err) | ||
| 863 | goto err; | ||
| 864 | fuse_copy_finish(cs); | ||
| 865 | |||
| 866 | down_read(&fc->killsb); | ||
| 867 | err = -ENOENT; | ||
| 868 | if (!fc->sb) | ||
| 869 | goto err_unlock; | ||
| 870 | |||
| 871 | err = fuse_reverse_inval_inode(fc->sb, outarg.ino, | ||
| 872 | outarg.off, outarg.len); | ||
| 873 | |||
| 874 | err_unlock: | ||
| 875 | up_read(&fc->killsb); | ||
| 876 | return err; | ||
| 877 | |||
| 878 | err: | ||
| 879 | fuse_copy_finish(cs); | ||
| 880 | return err; | ||
| 881 | } | ||
| 882 | |||
| 883 | static int fuse_notify_inval_entry(struct fuse_conn *fc, unsigned int size, | ||
| 884 | struct fuse_copy_state *cs) | ||
| 885 | { | ||
| 886 | struct fuse_notify_inval_entry_out outarg; | ||
| 887 | int err = -EINVAL; | ||
| 888 | char buf[FUSE_NAME_MAX+1]; | ||
| 889 | struct qstr name; | ||
| 890 | |||
| 891 | if (size < sizeof(outarg)) | ||
| 892 | goto err; | ||
| 893 | |||
| 894 | err = fuse_copy_one(cs, &outarg, sizeof(outarg)); | ||
| 895 | if (err) | ||
| 896 | goto err; | ||
| 897 | |||
| 898 | err = -ENAMETOOLONG; | ||
| 899 | if (outarg.namelen > FUSE_NAME_MAX) | ||
| 900 | goto err; | ||
| 901 | |||
| 902 | name.name = buf; | ||
| 903 | name.len = outarg.namelen; | ||
| 904 | err = fuse_copy_one(cs, buf, outarg.namelen + 1); | ||
| 905 | if (err) | ||
| 906 | goto err; | ||
| 907 | fuse_copy_finish(cs); | ||
| 908 | buf[outarg.namelen] = 0; | ||
| 909 | name.hash = full_name_hash(name.name, name.len); | ||
| 910 | |||
| 911 | down_read(&fc->killsb); | ||
| 912 | err = -ENOENT; | ||
| 913 | if (!fc->sb) | ||
| 914 | goto err_unlock; | ||
| 915 | |||
| 916 | err = fuse_reverse_inval_entry(fc->sb, outarg.parent, &name); | ||
| 917 | |||
| 918 | err_unlock: | ||
| 919 | up_read(&fc->killsb); | ||
| 920 | return err; | ||
| 921 | |||
| 922 | err: | ||
| 923 | fuse_copy_finish(cs); | ||
| 924 | return err; | ||
| 925 | } | ||
| 926 | |||
| 852 | static int fuse_notify(struct fuse_conn *fc, enum fuse_notify_code code, | 927 | static int fuse_notify(struct fuse_conn *fc, enum fuse_notify_code code, |
| 853 | unsigned int size, struct fuse_copy_state *cs) | 928 | unsigned int size, struct fuse_copy_state *cs) |
| 854 | { | 929 | { |
| @@ -856,6 +931,12 @@ static int fuse_notify(struct fuse_conn *fc, enum fuse_notify_code code, | |||
| 856 | case FUSE_NOTIFY_POLL: | 931 | case FUSE_NOTIFY_POLL: |
| 857 | return fuse_notify_poll(fc, size, cs); | 932 | return fuse_notify_poll(fc, size, cs); |
| 858 | 933 | ||
| 934 | case FUSE_NOTIFY_INVAL_INODE: | ||
| 935 | return fuse_notify_inval_inode(fc, size, cs); | ||
| 936 | |||
| 937 | case FUSE_NOTIFY_INVAL_ENTRY: | ||
| 938 | return fuse_notify_inval_entry(fc, size, cs); | ||
| 939 | |||
| 859 | default: | 940 | default: |
| 860 | fuse_copy_finish(cs); | 941 | fuse_copy_finish(cs); |
| 861 | return -EINVAL; | 942 | return -EINVAL; |
| @@ -910,7 +991,7 @@ static ssize_t fuse_dev_write(struct kiocb *iocb, const struct iovec *iov, | |||
| 910 | unsigned long nr_segs, loff_t pos) | 991 | unsigned long nr_segs, loff_t pos) |
| 911 | { | 992 | { |
| 912 | int err; | 993 | int err; |
| 913 | unsigned nbytes = iov_length(iov, nr_segs); | 994 | size_t nbytes = iov_length(iov, nr_segs); |
| 914 | struct fuse_req *req; | 995 | struct fuse_req *req; |
| 915 | struct fuse_out_header oh; | 996 | struct fuse_out_header oh; |
| 916 | struct fuse_copy_state cs; | 997 | struct fuse_copy_state cs; |
