diff options
Diffstat (limited to 'fs/fuse/dir.c')
-rw-r--r-- | fs/fuse/dir.c | 154 |
1 files changed, 75 insertions, 79 deletions
diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c index bd5a772d8ccf..d1acab931330 100644 --- a/fs/fuse/dir.c +++ b/fs/fuse/dir.c | |||
@@ -288,12 +288,11 @@ static struct dentry *fuse_lookup(struct inode *dir, struct dentry *entry, | |||
288 | static void fuse_sync_release(struct fuse_conn *fc, struct fuse_file *ff, | 288 | static void fuse_sync_release(struct fuse_conn *fc, struct fuse_file *ff, |
289 | u64 nodeid, int flags) | 289 | u64 nodeid, int flags) |
290 | { | 290 | { |
291 | struct fuse_req *req; | 291 | fuse_release_fill(ff, nodeid, flags, FUSE_RELEASE); |
292 | 292 | ff->reserved_req->force = 1; | |
293 | req = fuse_release_fill(ff, nodeid, flags, FUSE_RELEASE); | 293 | request_send(fc, ff->reserved_req); |
294 | req->force = 1; | 294 | fuse_put_request(fc, ff->reserved_req); |
295 | request_send(fc, req); | 295 | kfree(ff); |
296 | fuse_put_request(fc, req); | ||
297 | } | 296 | } |
298 | 297 | ||
299 | /* | 298 | /* |
@@ -664,7 +663,7 @@ static int fuse_link(struct dentry *entry, struct inode *newdir, | |||
664 | return err; | 663 | return err; |
665 | } | 664 | } |
666 | 665 | ||
667 | int fuse_do_getattr(struct inode *inode) | 666 | static int fuse_do_getattr(struct inode *inode) |
668 | { | 667 | { |
669 | int err; | 668 | int err; |
670 | struct fuse_attr_out arg; | 669 | struct fuse_attr_out arg; |
@@ -696,6 +695,20 @@ int fuse_do_getattr(struct inode *inode) | |||
696 | } | 695 | } |
697 | 696 | ||
698 | /* | 697 | /* |
698 | * Check if attributes are still valid, and if not send a GETATTR | ||
699 | * request to refresh them. | ||
700 | */ | ||
701 | static int fuse_refresh_attributes(struct inode *inode) | ||
702 | { | ||
703 | struct fuse_inode *fi = get_fuse_inode(inode); | ||
704 | |||
705 | if (fi->i_time < get_jiffies_64()) | ||
706 | return fuse_do_getattr(inode); | ||
707 | else | ||
708 | return 0; | ||
709 | } | ||
710 | |||
711 | /* | ||
699 | * Calling into a user-controlled filesystem gives the filesystem | 712 | * Calling into a user-controlled filesystem gives the filesystem |
700 | * daemon ptrace-like capabilities over the requester process. This | 713 | * daemon ptrace-like capabilities over the requester process. This |
701 | * means, that the filesystem daemon is able to record the exact | 714 | * means, that the filesystem daemon is able to record the exact |
@@ -724,30 +737,6 @@ static int fuse_allow_task(struct fuse_conn *fc, struct task_struct *task) | |||
724 | return 0; | 737 | return 0; |
725 | } | 738 | } |
726 | 739 | ||
727 | /* | ||
728 | * Check whether the inode attributes are still valid | ||
729 | * | ||
730 | * If the attribute validity timeout has expired, then fetch the fresh | ||
731 | * attributes with a 'getattr' request | ||
732 | * | ||
733 | * I'm not sure why cached attributes are never returned for the root | ||
734 | * inode, this is probably being too cautious. | ||
735 | */ | ||
736 | static int fuse_revalidate(struct dentry *entry) | ||
737 | { | ||
738 | struct inode *inode = entry->d_inode; | ||
739 | struct fuse_inode *fi = get_fuse_inode(inode); | ||
740 | struct fuse_conn *fc = get_fuse_conn(inode); | ||
741 | |||
742 | if (!fuse_allow_task(fc, current)) | ||
743 | return -EACCES; | ||
744 | if (get_node_id(inode) != FUSE_ROOT_ID && | ||
745 | fi->i_time >= get_jiffies_64()) | ||
746 | return 0; | ||
747 | |||
748 | return fuse_do_getattr(inode); | ||
749 | } | ||
750 | |||
751 | static int fuse_access(struct inode *inode, int mask) | 740 | static int fuse_access(struct inode *inode, int mask) |
752 | { | 741 | { |
753 | struct fuse_conn *fc = get_fuse_conn(inode); | 742 | struct fuse_conn *fc = get_fuse_conn(inode); |
@@ -795,16 +784,31 @@ static int fuse_access(struct inode *inode, int mask) | |||
795 | static int fuse_permission(struct inode *inode, int mask, struct nameidata *nd) | 784 | static int fuse_permission(struct inode *inode, int mask, struct nameidata *nd) |
796 | { | 785 | { |
797 | struct fuse_conn *fc = get_fuse_conn(inode); | 786 | struct fuse_conn *fc = get_fuse_conn(inode); |
787 | bool refreshed = false; | ||
788 | int err = 0; | ||
798 | 789 | ||
799 | if (!fuse_allow_task(fc, current)) | 790 | if (!fuse_allow_task(fc, current)) |
800 | return -EACCES; | 791 | return -EACCES; |
801 | else if (fc->flags & FUSE_DEFAULT_PERMISSIONS) { | 792 | |
793 | /* | ||
794 | * If attributes are needed, refresh them before proceeding | ||
795 | */ | ||
796 | if ((fc->flags & FUSE_DEFAULT_PERMISSIONS) || | ||
797 | ((mask & MAY_EXEC) && S_ISREG(inode->i_mode))) { | ||
798 | err = fuse_refresh_attributes(inode); | ||
799 | if (err) | ||
800 | return err; | ||
801 | |||
802 | refreshed = true; | ||
803 | } | ||
804 | |||
805 | if (fc->flags & FUSE_DEFAULT_PERMISSIONS) { | ||
802 | int err = generic_permission(inode, mask, NULL); | 806 | int err = generic_permission(inode, mask, NULL); |
803 | 807 | ||
804 | /* If permission is denied, try to refresh file | 808 | /* If permission is denied, try to refresh file |
805 | attributes. This is also needed, because the root | 809 | attributes. This is also needed, because the root |
806 | node will at first have no permissions */ | 810 | node will at first have no permissions */ |
807 | if (err == -EACCES) { | 811 | if (err == -EACCES && !refreshed) { |
808 | err = fuse_do_getattr(inode); | 812 | err = fuse_do_getattr(inode); |
809 | if (!err) | 813 | if (!err) |
810 | err = generic_permission(inode, mask, NULL); | 814 | err = generic_permission(inode, mask, NULL); |
@@ -814,17 +818,19 @@ static int fuse_permission(struct inode *inode, int mask, struct nameidata *nd) | |||
814 | exist. So if permissions are revoked this won't be | 818 | exist. So if permissions are revoked this won't be |
815 | noticed immediately, only after the attribute | 819 | noticed immediately, only after the attribute |
816 | timeout has expired */ | 820 | timeout has expired */ |
817 | 821 | } else if (nd && (nd->flags & (LOOKUP_ACCESS | LOOKUP_CHDIR))) { | |
818 | return err; | 822 | err = fuse_access(inode, mask); |
819 | } else { | 823 | } else if ((mask & MAY_EXEC) && S_ISREG(inode->i_mode)) { |
820 | int mode = inode->i_mode; | 824 | if (!(inode->i_mode & S_IXUGO)) { |
821 | if ((mask & MAY_EXEC) && !S_ISDIR(mode) && !(mode & S_IXUGO)) | 825 | if (refreshed) |
822 | return -EACCES; | 826 | return -EACCES; |
823 | 827 | ||
824 | if (nd && (nd->flags & (LOOKUP_ACCESS | LOOKUP_CHDIR))) | 828 | err = fuse_do_getattr(inode); |
825 | return fuse_access(inode, mask); | 829 | if (!err && !(inode->i_mode & S_IXUGO)) |
826 | return 0; | 830 | return -EACCES; |
831 | } | ||
827 | } | 832 | } |
833 | return err; | ||
828 | } | 834 | } |
829 | 835 | ||
830 | static int parse_dirfile(char *buf, size_t nbytes, struct file *file, | 836 | static int parse_dirfile(char *buf, size_t nbytes, struct file *file, |
@@ -859,6 +865,7 @@ static int fuse_readdir(struct file *file, void *dstbuf, filldir_t filldir) | |||
859 | struct page *page; | 865 | struct page *page; |
860 | struct inode *inode = file->f_path.dentry->d_inode; | 866 | struct inode *inode = file->f_path.dentry->d_inode; |
861 | struct fuse_conn *fc = get_fuse_conn(inode); | 867 | struct fuse_conn *fc = get_fuse_conn(inode); |
868 | struct fuse_file *ff = file->private_data; | ||
862 | struct fuse_req *req; | 869 | struct fuse_req *req; |
863 | 870 | ||
864 | if (is_bad_inode(inode)) | 871 | if (is_bad_inode(inode)) |
@@ -875,7 +882,7 @@ static int fuse_readdir(struct file *file, void *dstbuf, filldir_t filldir) | |||
875 | } | 882 | } |
876 | req->num_pages = 1; | 883 | req->num_pages = 1; |
877 | req->pages[0] = page; | 884 | req->pages[0] = page; |
878 | fuse_read_fill(req, file, inode, file->f_pos, PAGE_SIZE, FUSE_READDIR); | 885 | fuse_read_fill(req, ff, inode, file->f_pos, PAGE_SIZE, FUSE_READDIR); |
879 | request_send(fc, req); | 886 | request_send(fc, req); |
880 | nbytes = req->out.args[0].size; | 887 | nbytes = req->out.args[0].size; |
881 | err = req->out.h.error; | 888 | err = req->out.h.error; |
@@ -980,23 +987,6 @@ static void iattr_to_fattr(struct iattr *iattr, struct fuse_setattr_in *arg) | |||
980 | } | 987 | } |
981 | } | 988 | } |
982 | 989 | ||
983 | static void fuse_vmtruncate(struct inode *inode, loff_t offset) | ||
984 | { | ||
985 | struct fuse_conn *fc = get_fuse_conn(inode); | ||
986 | int need_trunc; | ||
987 | |||
988 | spin_lock(&fc->lock); | ||
989 | need_trunc = inode->i_size > offset; | ||
990 | i_size_write(inode, offset); | ||
991 | spin_unlock(&fc->lock); | ||
992 | |||
993 | if (need_trunc) { | ||
994 | struct address_space *mapping = inode->i_mapping; | ||
995 | unmap_mapping_range(mapping, offset + PAGE_SIZE - 1, 0, 1); | ||
996 | truncate_inode_pages(mapping, offset); | ||
997 | } | ||
998 | } | ||
999 | |||
1000 | /* | 990 | /* |
1001 | * Set attributes, and at the same time refresh them. | 991 | * Set attributes, and at the same time refresh them. |
1002 | * | 992 | * |
@@ -1014,7 +1004,6 @@ static int fuse_setattr(struct dentry *entry, struct iattr *attr) | |||
1014 | struct fuse_setattr_in inarg; | 1004 | struct fuse_setattr_in inarg; |
1015 | struct fuse_attr_out outarg; | 1005 | struct fuse_attr_out outarg; |
1016 | int err; | 1006 | int err; |
1017 | int is_truncate = 0; | ||
1018 | 1007 | ||
1019 | if (fc->flags & FUSE_DEFAULT_PERMISSIONS) { | 1008 | if (fc->flags & FUSE_DEFAULT_PERMISSIONS) { |
1020 | err = inode_change_ok(inode, attr); | 1009 | err = inode_change_ok(inode, attr); |
@@ -1024,7 +1013,6 @@ static int fuse_setattr(struct dentry *entry, struct iattr *attr) | |||
1024 | 1013 | ||
1025 | if (attr->ia_valid & ATTR_SIZE) { | 1014 | if (attr->ia_valid & ATTR_SIZE) { |
1026 | unsigned long limit; | 1015 | unsigned long limit; |
1027 | is_truncate = 1; | ||
1028 | if (IS_SWAPFILE(inode)) | 1016 | if (IS_SWAPFILE(inode)) |
1029 | return -ETXTBSY; | 1017 | return -ETXTBSY; |
1030 | limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur; | 1018 | limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur; |
@@ -1051,30 +1039,38 @@ static int fuse_setattr(struct dentry *entry, struct iattr *attr) | |||
1051 | request_send(fc, req); | 1039 | request_send(fc, req); |
1052 | err = req->out.h.error; | 1040 | err = req->out.h.error; |
1053 | fuse_put_request(fc, req); | 1041 | fuse_put_request(fc, req); |
1054 | if (!err) { | 1042 | if (err) { |
1055 | if ((inode->i_mode ^ outarg.attr.mode) & S_IFMT) { | 1043 | if (err == -EINTR) |
1056 | make_bad_inode(inode); | 1044 | fuse_invalidate_attr(inode); |
1057 | err = -EIO; | 1045 | return err; |
1058 | } else { | 1046 | } |
1059 | if (is_truncate) | ||
1060 | fuse_vmtruncate(inode, outarg.attr.size); | ||
1061 | fuse_change_attributes(inode, &outarg.attr); | ||
1062 | fi->i_time = time_to_jiffies(outarg.attr_valid, | ||
1063 | outarg.attr_valid_nsec); | ||
1064 | } | ||
1065 | } else if (err == -EINTR) | ||
1066 | fuse_invalidate_attr(inode); | ||
1067 | 1047 | ||
1068 | return err; | 1048 | if ((inode->i_mode ^ outarg.attr.mode) & S_IFMT) { |
1049 | make_bad_inode(inode); | ||
1050 | return -EIO; | ||
1051 | } | ||
1052 | |||
1053 | fuse_change_attributes(inode, &outarg.attr); | ||
1054 | fi->i_time = time_to_jiffies(outarg.attr_valid, outarg.attr_valid_nsec); | ||
1055 | return 0; | ||
1069 | } | 1056 | } |
1070 | 1057 | ||
1071 | static int fuse_getattr(struct vfsmount *mnt, struct dentry *entry, | 1058 | static int fuse_getattr(struct vfsmount *mnt, struct dentry *entry, |
1072 | struct kstat *stat) | 1059 | struct kstat *stat) |
1073 | { | 1060 | { |
1074 | struct inode *inode = entry->d_inode; | 1061 | struct inode *inode = entry->d_inode; |
1075 | int err = fuse_revalidate(entry); | 1062 | struct fuse_inode *fi = get_fuse_inode(inode); |
1076 | if (!err) | 1063 | struct fuse_conn *fc = get_fuse_conn(inode); |
1064 | int err; | ||
1065 | |||
1066 | if (!fuse_allow_task(fc, current)) | ||
1067 | return -EACCES; | ||
1068 | |||
1069 | err = fuse_refresh_attributes(inode); | ||
1070 | if (!err) { | ||
1077 | generic_fillattr(inode, stat); | 1071 | generic_fillattr(inode, stat); |
1072 | stat->mode = fi->orig_i_mode; | ||
1073 | } | ||
1078 | 1074 | ||
1079 | return err; | 1075 | return err; |
1080 | } | 1076 | } |