aboutsummaryrefslogtreecommitdiffstats
path: root/fs/fuse/dev.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/fuse/dev.c')
-rw-r--r--fs/fuse/dev.c92
1 files changed, 87 insertions, 5 deletions
diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c
index 8fed2ed12f38..cbceacbc0bf9 100644
--- a/fs/fuse/dev.c
+++ b/fs/fuse/dev.c
@@ -16,6 +16,7 @@
16#include <linux/pagemap.h> 16#include <linux/pagemap.h>
17#include <linux/file.h> 17#include <linux/file.h>
18#include <linux/slab.h> 18#include <linux/slab.h>
19#include <linux/blkdev.h>
19 20
20MODULE_ALIAS_MISCDEV(FUSE_MINOR); 21MODULE_ALIAS_MISCDEV(FUSE_MINOR);
21 22
@@ -286,8 +287,8 @@ __releases(&fc->lock)
286 } 287 }
287 if (fc->num_background == FUSE_CONGESTION_THRESHOLD && 288 if (fc->num_background == FUSE_CONGESTION_THRESHOLD &&
288 fc->connected && fc->bdi_initialized) { 289 fc->connected && fc->bdi_initialized) {
289 clear_bdi_congested(&fc->bdi, READ); 290 clear_bdi_congested(&fc->bdi, BLK_RW_SYNC);
290 clear_bdi_congested(&fc->bdi, WRITE); 291 clear_bdi_congested(&fc->bdi, BLK_RW_ASYNC);
291 } 292 }
292 fc->num_background--; 293 fc->num_background--;
293 fc->active_background--; 294 fc->active_background--;
@@ -414,8 +415,8 @@ static void fuse_request_send_nowait_locked(struct fuse_conn *fc,
414 fc->blocked = 1; 415 fc->blocked = 1;
415 if (fc->num_background == FUSE_CONGESTION_THRESHOLD && 416 if (fc->num_background == FUSE_CONGESTION_THRESHOLD &&
416 fc->bdi_initialized) { 417 fc->bdi_initialized) {
417 set_bdi_congested(&fc->bdi, READ); 418 set_bdi_congested(&fc->bdi, BLK_RW_SYNC);
418 set_bdi_congested(&fc->bdi, WRITE); 419 set_bdi_congested(&fc->bdi, BLK_RW_ASYNC);
419 } 420 }
420 list_add_tail(&req->list, &fc->bg_queue); 421 list_add_tail(&req->list, &fc->bg_queue);
421 flush_bg_queue(fc); 422 flush_bg_queue(fc);
@@ -849,6 +850,81 @@ err:
849 return err; 850 return err;
850} 851}
851 852
853static int fuse_notify_inval_inode(struct fuse_conn *fc, unsigned int size,
854 struct fuse_copy_state *cs)
855{
856 struct fuse_notify_inval_inode_out outarg;
857 int err = -EINVAL;
858
859 if (size != sizeof(outarg))
860 goto err;
861
862 err = fuse_copy_one(cs, &outarg, sizeof(outarg));
863 if (err)
864 goto err;
865 fuse_copy_finish(cs);
866
867 down_read(&fc->killsb);
868 err = -ENOENT;
869 if (!fc->sb)
870 goto err_unlock;
871
872 err = fuse_reverse_inval_inode(fc->sb, outarg.ino,
873 outarg.off, outarg.len);
874
875err_unlock:
876 up_read(&fc->killsb);
877 return err;
878
879err:
880 fuse_copy_finish(cs);
881 return err;
882}
883
884static int fuse_notify_inval_entry(struct fuse_conn *fc, unsigned int size,
885 struct fuse_copy_state *cs)
886{
887 struct fuse_notify_inval_entry_out outarg;
888 int err = -EINVAL;
889 char buf[FUSE_NAME_MAX+1];
890 struct qstr name;
891
892 if (size < sizeof(outarg))
893 goto err;
894
895 err = fuse_copy_one(cs, &outarg, sizeof(outarg));
896 if (err)
897 goto err;
898
899 err = -ENAMETOOLONG;
900 if (outarg.namelen > FUSE_NAME_MAX)
901 goto err;
902
903 name.name = buf;
904 name.len = outarg.namelen;
905 err = fuse_copy_one(cs, buf, outarg.namelen + 1);
906 if (err)
907 goto err;
908 fuse_copy_finish(cs);
909 buf[outarg.namelen] = 0;
910 name.hash = full_name_hash(name.name, name.len);
911
912 down_read(&fc->killsb);
913 err = -ENOENT;
914 if (!fc->sb)
915 goto err_unlock;
916
917 err = fuse_reverse_inval_entry(fc->sb, outarg.parent, &name);
918
919err_unlock:
920 up_read(&fc->killsb);
921 return err;
922
923err:
924 fuse_copy_finish(cs);
925 return err;
926}
927
852static int fuse_notify(struct fuse_conn *fc, enum fuse_notify_code code, 928static int fuse_notify(struct fuse_conn *fc, enum fuse_notify_code code,
853 unsigned int size, struct fuse_copy_state *cs) 929 unsigned int size, struct fuse_copy_state *cs)
854{ 930{
@@ -856,6 +932,12 @@ static int fuse_notify(struct fuse_conn *fc, enum fuse_notify_code code,
856 case FUSE_NOTIFY_POLL: 932 case FUSE_NOTIFY_POLL:
857 return fuse_notify_poll(fc, size, cs); 933 return fuse_notify_poll(fc, size, cs);
858 934
935 case FUSE_NOTIFY_INVAL_INODE:
936 return fuse_notify_inval_inode(fc, size, cs);
937
938 case FUSE_NOTIFY_INVAL_ENTRY:
939 return fuse_notify_inval_entry(fc, size, cs);
940
859 default: 941 default:
860 fuse_copy_finish(cs); 942 fuse_copy_finish(cs);
861 return -EINVAL; 943 return -EINVAL;
@@ -910,7 +992,7 @@ static ssize_t fuse_dev_write(struct kiocb *iocb, const struct iovec *iov,
910 unsigned long nr_segs, loff_t pos) 992 unsigned long nr_segs, loff_t pos)
911{ 993{
912 int err; 994 int err;
913 unsigned nbytes = iov_length(iov, nr_segs); 995 size_t nbytes = iov_length(iov, nr_segs);
914 struct fuse_req *req; 996 struct fuse_req *req;
915 struct fuse_out_header oh; 997 struct fuse_out_header oh;
916 struct fuse_copy_state cs; 998 struct fuse_copy_state cs;