From 04f8ab283b79b0f8c391f4d9119e8524007e9857 Mon Sep 17 00:00:00 2001 From: Miklos Szeredi Date: Tue, 16 Oct 2007 23:31:06 -0700 Subject: [PATCH] --- yaml --- r: 70761 b: refs/heads/master c: e8e961574b5b417d3fc277cbf436081fce4fc2e1 h: refs/heads/master i: 70759: e2db2536ffdacfa29d7416391aca81136b9fc49e v: v3 --- [refs] | 2 +- trunk/fs/fuse/dir.c | 49 ++++++++++++++++++++++++++++----------------- 2 files changed, 32 insertions(+), 19 deletions(-) diff --git a/[refs] b/[refs] index d0d78acc5aff..cc74fddaf331 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: c9c9d7df5f8aed8b738f1ace45700e2001c1faeb +refs/heads/master: e8e961574b5b417d3fc277cbf436081fce4fc2e1 diff --git a/trunk/fs/fuse/dir.c b/trunk/fs/fuse/dir.c index 8ea4ea13ec5f..d1acab931330 100644 --- a/trunk/fs/fuse/dir.c +++ b/trunk/fs/fuse/dir.c @@ -694,6 +694,20 @@ static int fuse_do_getattr(struct inode *inode) return err; } +/* + * Check if attributes are still valid, and if not send a GETATTR + * request to refresh them. + */ +static int fuse_refresh_attributes(struct inode *inode) +{ + struct fuse_inode *fi = get_fuse_inode(inode); + + if (fi->i_time < get_jiffies_64()) + return fuse_do_getattr(inode); + else + return 0; +} + /* * Calling into a user-controlled filesystem gives the filesystem * daemon ptrace-like capabilities over the requester process. This @@ -770,7 +784,6 @@ static int fuse_access(struct inode *inode, int mask) static int fuse_permission(struct inode *inode, int mask, struct nameidata *nd) { struct fuse_conn *fc = get_fuse_conn(inode); - struct fuse_inode *fi = get_fuse_inode(inode); bool refreshed = false; int err = 0; @@ -778,12 +791,11 @@ static int fuse_permission(struct inode *inode, int mask, struct nameidata *nd) return -EACCES; /* - * If attributes are needed, but are stale, refresh them - * before proceeding + * If attributes are needed, refresh them before proceeding */ - if (((fc->flags & FUSE_DEFAULT_PERMISSIONS) || (mask & MAY_EXEC)) && - fi->i_time < get_jiffies_64()) { - err = fuse_do_getattr(inode); + if ((fc->flags & FUSE_DEFAULT_PERMISSIONS) || + ((mask & MAY_EXEC) && S_ISREG(inode->i_mode))) { + err = fuse_refresh_attributes(inode); if (err) return err; @@ -806,14 +818,17 @@ static int fuse_permission(struct inode *inode, int mask, struct nameidata *nd) exist. So if permissions are revoked this won't be noticed immediately, only after the attribute timeout has expired */ - - } else { - int mode = inode->i_mode; - if ((mask & MAY_EXEC) && !S_ISDIR(mode) && !(mode & S_IXUGO)) - return -EACCES; - - if (nd && (nd->flags & (LOOKUP_ACCESS | LOOKUP_CHDIR))) - return fuse_access(inode, mask); + } else if (nd && (nd->flags & (LOOKUP_ACCESS | LOOKUP_CHDIR))) { + err = fuse_access(inode, mask); + } else if ((mask & MAY_EXEC) && S_ISREG(inode->i_mode)) { + if (!(inode->i_mode & S_IXUGO)) { + if (refreshed) + return -EACCES; + + err = fuse_do_getattr(inode); + if (!err && !(inode->i_mode & S_IXUGO)) + return -EACCES; + } } return err; } @@ -1046,14 +1061,12 @@ static int fuse_getattr(struct vfsmount *mnt, struct dentry *entry, struct inode *inode = entry->d_inode; struct fuse_inode *fi = get_fuse_inode(inode); struct fuse_conn *fc = get_fuse_conn(inode); - int err = 0; + int err; if (!fuse_allow_task(fc, current)) return -EACCES; - if (fi->i_time < get_jiffies_64()) - err = fuse_do_getattr(inode); - + err = fuse_refresh_attributes(inode); if (!err) { generic_fillattr(inode, stat); stat->mode = fi->orig_i_mode;