dir.c (1fb69e7817296da8a6824804bb206ca1e7f31425) | dir.c (c79e322f63592c00b25b17af6a1782fad6c6fe6e) |
---|---|
1/* 2 FUSE: Filesystem in Userspace 3 Copyright (C) 2001-2006 Miklos Szeredi <miklos@szeredi.hu> 4 5 This program can be distributed under the terms of the GNU GPL. 6 See the file COPYING. 7*/ 8 --- 691 unchanged lines hidden (view full) --- 700 stat->mtime.tv_nsec = attr->mtimensec; 701 stat->ctime.tv_sec = attr->ctime; 702 stat->ctime.tv_nsec = attr->ctimensec; 703 stat->size = attr->size; 704 stat->blocks = attr->blocks; 705 stat->blksize = (1 << inode->i_blkbits); 706} 707 | 1/* 2 FUSE: Filesystem in Userspace 3 Copyright (C) 2001-2006 Miklos Szeredi <miklos@szeredi.hu> 4 5 This program can be distributed under the terms of the GNU GPL. 6 See the file COPYING. 7*/ 8 --- 691 unchanged lines hidden (view full) --- 700 stat->mtime.tv_nsec = attr->mtimensec; 701 stat->ctime.tv_sec = attr->ctime; 702 stat->ctime.tv_nsec = attr->ctimensec; 703 stat->size = attr->size; 704 stat->blocks = attr->blocks; 705 stat->blksize = (1 << inode->i_blkbits); 706} 707 |
708static int fuse_do_getattr(struct inode *inode, struct kstat *stat) | 708static int fuse_do_getattr(struct inode *inode, struct kstat *stat, 709 struct file *file) |
709{ 710 int err; | 710{ 711 int err; |
711 struct fuse_attr_out arg; | 712 struct fuse_getattr_in inarg; 713 struct fuse_attr_out outarg; |
712 struct fuse_conn *fc = get_fuse_conn(inode); 713 struct fuse_req *req; 714 u64 attr_version; 715 716 req = fuse_get_req(fc); 717 if (IS_ERR(req)) 718 return PTR_ERR(req); 719 720 spin_lock(&fc->lock); 721 attr_version = fc->attr_version; 722 spin_unlock(&fc->lock); 723 | 714 struct fuse_conn *fc = get_fuse_conn(inode); 715 struct fuse_req *req; 716 u64 attr_version; 717 718 req = fuse_get_req(fc); 719 if (IS_ERR(req)) 720 return PTR_ERR(req); 721 722 spin_lock(&fc->lock); 723 attr_version = fc->attr_version; 724 spin_unlock(&fc->lock); 725 |
726 memset(&inarg, 0, sizeof(inarg)); 727 /* Directories have separate file-handle space */ 728 if (file && S_ISREG(inode->i_mode)) { 729 struct fuse_file *ff = file->private_data; 730 731 inarg.getattr_flags |= FUSE_GETATTR_FH; 732 inarg.fh = ff->fh; 733 } |
|
724 req->in.h.opcode = FUSE_GETATTR; 725 req->in.h.nodeid = get_node_id(inode); | 734 req->in.h.opcode = FUSE_GETATTR; 735 req->in.h.nodeid = get_node_id(inode); |
736 req->in.numargs = 1; 737 req->in.args[0].size = sizeof(inarg); 738 req->in.args[0].value = &inarg; |
|
726 req->out.numargs = 1; | 739 req->out.numargs = 1; |
727 req->out.args[0].size = sizeof(arg); 728 req->out.args[0].value = &arg; | 740 req->out.args[0].size = sizeof(outarg); 741 req->out.args[0].value = &outarg; |
729 request_send(fc, req); 730 err = req->out.h.error; 731 fuse_put_request(fc, req); 732 if (!err) { | 742 request_send(fc, req); 743 err = req->out.h.error; 744 fuse_put_request(fc, req); 745 if (!err) { |
733 if ((inode->i_mode ^ arg.attr.mode) & S_IFMT) { | 746 if ((inode->i_mode ^ outarg.attr.mode) & S_IFMT) { |
734 make_bad_inode(inode); 735 err = -EIO; 736 } else { | 747 make_bad_inode(inode); 748 err = -EIO; 749 } else { |
737 fuse_change_attributes(inode, &arg.attr, 738 attr_timeout(&arg), | 750 fuse_change_attributes(inode, &outarg.attr, 751 attr_timeout(&outarg), |
739 attr_version); 740 if (stat) | 752 attr_version); 753 if (stat) |
741 fuse_fillattr(inode, &arg.attr, stat); | 754 fuse_fillattr(inode, &outarg.attr, stat); |
742 } 743 } 744 return err; 745} 746 747/* 748 * Calling into a user-controlled filesystem gives the filesystem 749 * daemon ptrace-like capabilities over the requester process. This --- 78 unchanged lines hidden (view full) --- 828 829 /* 830 * If attributes are needed, refresh them before proceeding 831 */ 832 if ((fc->flags & FUSE_DEFAULT_PERMISSIONS) || 833 ((mask & MAY_EXEC) && S_ISREG(inode->i_mode))) { 834 struct fuse_inode *fi = get_fuse_inode(inode); 835 if (fi->i_time < get_jiffies_64()) { | 755 } 756 } 757 return err; 758} 759 760/* 761 * Calling into a user-controlled filesystem gives the filesystem 762 * daemon ptrace-like capabilities over the requester process. This --- 78 unchanged lines hidden (view full) --- 841 842 /* 843 * If attributes are needed, refresh them before proceeding 844 */ 845 if ((fc->flags & FUSE_DEFAULT_PERMISSIONS) || 846 ((mask & MAY_EXEC) && S_ISREG(inode->i_mode))) { 847 struct fuse_inode *fi = get_fuse_inode(inode); 848 if (fi->i_time < get_jiffies_64()) { |
836 err = fuse_do_getattr(inode, NULL); | 849 err = fuse_do_getattr(inode, NULL, NULL); |
837 if (err) 838 return err; 839 840 refreshed = true; 841 } 842 } 843 844 if (fc->flags & FUSE_DEFAULT_PERMISSIONS) { 845 int err = generic_permission(inode, mask, NULL); 846 847 /* If permission is denied, try to refresh file 848 attributes. This is also needed, because the root 849 node will at first have no permissions */ 850 if (err == -EACCES && !refreshed) { | 850 if (err) 851 return err; 852 853 refreshed = true; 854 } 855 } 856 857 if (fc->flags & FUSE_DEFAULT_PERMISSIONS) { 858 int err = generic_permission(inode, mask, NULL); 859 860 /* If permission is denied, try to refresh file 861 attributes. This is also needed, because the root 862 node will at first have no permissions */ 863 if (err == -EACCES && !refreshed) { |
851 err = fuse_do_getattr(inode, NULL); | 864 err = fuse_do_getattr(inode, NULL, NULL); |
852 if (!err) 853 err = generic_permission(inode, mask, NULL); 854 } 855 856 /* Note: the opposite of the above test does not 857 exist. So if permissions are revoked this won't be 858 noticed immediately, only after the attribute 859 timeout has expired */ 860 } else if (nd && (nd->flags & (LOOKUP_ACCESS | LOOKUP_CHDIR))) { 861 err = fuse_access(inode, mask); 862 } else if ((mask & MAY_EXEC) && S_ISREG(inode->i_mode)) { 863 if (!(inode->i_mode & S_IXUGO)) { 864 if (refreshed) 865 return -EACCES; 866 | 865 if (!err) 866 err = generic_permission(inode, mask, NULL); 867 } 868 869 /* Note: the opposite of the above test does not 870 exist. So if permissions are revoked this won't be 871 noticed immediately, only after the attribute 872 timeout has expired */ 873 } else if (nd && (nd->flags & (LOOKUP_ACCESS | LOOKUP_CHDIR))) { 874 err = fuse_access(inode, mask); 875 } else if ((mask & MAY_EXEC) && S_ISREG(inode->i_mode)) { 876 if (!(inode->i_mode & S_IXUGO)) { 877 if (refreshed) 878 return -EACCES; 879 |
867 err = fuse_do_getattr(inode, NULL); | 880 err = fuse_do_getattr(inode, NULL, NULL); |
868 if (!err && !(inode->i_mode & S_IXUGO)) 869 return -EACCES; 870 } 871 } 872 return err; 873} 874 875static int parse_dirfile(char *buf, size_t nbytes, struct file *file, --- 226 unchanged lines hidden (view full) --- 1102 struct fuse_inode *fi = get_fuse_inode(inode); 1103 struct fuse_conn *fc = get_fuse_conn(inode); 1104 int err; 1105 1106 if (!fuse_allow_task(fc, current)) 1107 return -EACCES; 1108 1109 if (fi->i_time < get_jiffies_64()) | 881 if (!err && !(inode->i_mode & S_IXUGO)) 882 return -EACCES; 883 } 884 } 885 return err; 886} 887 888static int parse_dirfile(char *buf, size_t nbytes, struct file *file, --- 226 unchanged lines hidden (view full) --- 1115 struct fuse_inode *fi = get_fuse_inode(inode); 1116 struct fuse_conn *fc = get_fuse_conn(inode); 1117 int err; 1118 1119 if (!fuse_allow_task(fc, current)) 1120 return -EACCES; 1121 1122 if (fi->i_time < get_jiffies_64()) |
1110 err = fuse_do_getattr(inode, stat); | 1123 err = fuse_do_getattr(inode, stat, NULL); |
1111 else { 1112 err = 0; 1113 generic_fillattr(inode, stat); 1114 stat->mode = fi->orig_i_mode; 1115 } 1116 1117 return err; 1118} --- 233 unchanged lines hidden --- | 1124 else { 1125 err = 0; 1126 generic_fillattr(inode, stat); 1127 stat->mode = fi->orig_i_mode; 1128 } 1129 1130 return err; 1131} --- 233 unchanged lines hidden --- |