diff options
| author | Miklos Szeredi <mszeredi@suse.cz> | 2007-10-17 02:31:06 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-10-17 11:43:04 -0400 |
| commit | e8e961574b5b417d3fc277cbf436081fce4fc2e1 (patch) | |
| tree | 28e73ea3666f4e2778d0d52c511be4d8e32b9e26 /fs/fuse | |
| parent | c9c9d7df5f8aed8b738f1ace45700e2001c1faeb (diff) | |
fuse: clean up execute permission checking
Define a new function fuse_refresh_attributes() that conditionally refreshes
the attributes based on the validity timeout.
In fuse_permission() only refresh the attributes for checking the execute bits
if necessary.
Signed-off-by: Miklos Szeredi <mszeredi@suse.cz>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs/fuse')
| -rw-r--r-- | fs/fuse/dir.c | 49 |
1 files changed, 31 insertions, 18 deletions
diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c index 8ea4ea13ec5f..d1acab931330 100644 --- a/fs/fuse/dir.c +++ b/fs/fuse/dir.c | |||
| @@ -695,6 +695,20 @@ static int fuse_do_getattr(struct inode *inode) | |||
| 695 | } | 695 | } |
| 696 | 696 | ||
| 697 | /* | 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 | /* | ||
| 698 | * Calling into a user-controlled filesystem gives the filesystem | 712 | * Calling into a user-controlled filesystem gives the filesystem |
| 699 | * daemon ptrace-like capabilities over the requester process. This | 713 | * daemon ptrace-like capabilities over the requester process. This |
| 700 | * means, that the filesystem daemon is able to record the exact | 714 | * means, that the filesystem daemon is able to record the exact |
| @@ -770,7 +784,6 @@ static int fuse_access(struct inode *inode, int mask) | |||
| 770 | 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) |
| 771 | { | 785 | { |
| 772 | struct fuse_conn *fc = get_fuse_conn(inode); | 786 | struct fuse_conn *fc = get_fuse_conn(inode); |
| 773 | struct fuse_inode *fi = get_fuse_inode(inode); | ||
| 774 | bool refreshed = false; | 787 | bool refreshed = false; |
| 775 | int err = 0; | 788 | int err = 0; |
| 776 | 789 | ||
| @@ -778,12 +791,11 @@ static int fuse_permission(struct inode *inode, int mask, struct nameidata *nd) | |||
| 778 | return -EACCES; | 791 | return -EACCES; |
| 779 | 792 | ||
| 780 | /* | 793 | /* |
| 781 | * If attributes are needed, but are stale, refresh them | 794 | * If attributes are needed, refresh them before proceeding |
| 782 | * before proceeding | ||
| 783 | */ | 795 | */ |
| 784 | if (((fc->flags & FUSE_DEFAULT_PERMISSIONS) || (mask & MAY_EXEC)) && | 796 | if ((fc->flags & FUSE_DEFAULT_PERMISSIONS) || |
| 785 | fi->i_time < get_jiffies_64()) { | 797 | ((mask & MAY_EXEC) && S_ISREG(inode->i_mode))) { |
| 786 | err = fuse_do_getattr(inode); | 798 | err = fuse_refresh_attributes(inode); |
| 787 | if (err) | 799 | if (err) |
| 788 | return err; | 800 | return err; |
| 789 | 801 | ||
| @@ -806,14 +818,17 @@ static int fuse_permission(struct inode *inode, int mask, struct nameidata *nd) | |||
| 806 | exist. So if permissions are revoked this won't be | 818 | exist. So if permissions are revoked this won't be |
| 807 | noticed immediately, only after the attribute | 819 | noticed immediately, only after the attribute |
| 808 | timeout has expired */ | 820 | timeout has expired */ |
| 809 | 821 | } else if (nd && (nd->flags & (LOOKUP_ACCESS | LOOKUP_CHDIR))) { | |
| 810 | } else { | 822 | err = fuse_access(inode, mask); |
| 811 | int mode = inode->i_mode; | 823 | } else if ((mask & MAY_EXEC) && S_ISREG(inode->i_mode)) { |
| 812 | if ((mask & MAY_EXEC) && !S_ISDIR(mode) && !(mode & S_IXUGO)) | 824 | if (!(inode->i_mode & S_IXUGO)) { |
| 813 | return -EACCES; | 825 | if (refreshed) |
| 814 | 826 | return -EACCES; | |
| 815 | if (nd && (nd->flags & (LOOKUP_ACCESS | LOOKUP_CHDIR))) | 827 | |
| 816 | return fuse_access(inode, mask); | 828 | err = fuse_do_getattr(inode); |
| 829 | if (!err && !(inode->i_mode & S_IXUGO)) | ||
| 830 | return -EACCES; | ||
| 831 | } | ||
| 817 | } | 832 | } |
| 818 | return err; | 833 | return err; |
| 819 | } | 834 | } |
| @@ -1046,14 +1061,12 @@ static int fuse_getattr(struct vfsmount *mnt, struct dentry *entry, | |||
| 1046 | struct inode *inode = entry->d_inode; | 1061 | struct inode *inode = entry->d_inode; |
| 1047 | struct fuse_inode *fi = get_fuse_inode(inode); | 1062 | struct fuse_inode *fi = get_fuse_inode(inode); |
| 1048 | struct fuse_conn *fc = get_fuse_conn(inode); | 1063 | struct fuse_conn *fc = get_fuse_conn(inode); |
| 1049 | int err = 0; | 1064 | int err; |
| 1050 | 1065 | ||
| 1051 | if (!fuse_allow_task(fc, current)) | 1066 | if (!fuse_allow_task(fc, current)) |
| 1052 | return -EACCES; | 1067 | return -EACCES; |
| 1053 | 1068 | ||
| 1054 | if (fi->i_time < get_jiffies_64()) | 1069 | err = fuse_refresh_attributes(inode); |
| 1055 | err = fuse_do_getattr(inode); | ||
| 1056 | |||
| 1057 | if (!err) { | 1070 | if (!err) { |
| 1058 | generic_fillattr(inode, stat); | 1071 | generic_fillattr(inode, stat); |
| 1059 | stat->mode = fi->orig_i_mode; | 1072 | stat->mode = fi->orig_i_mode; |
