It is not sufficient to depend on the the "filesystem is readonly" tests in dentry_permission as it does not check if the vfsmnt is readonly. All call sites already call mnt_want_write or __mnt_is_readonly which includes the test on MS_RDONLY. So remove this test from dentry_permission as it simply duplicates tests done elsewhere. This allows ovl_permission to be significantly simplified. Cc: Dave Hansen <haveblue@xxxxxxxxxx> Signed-off-by: NeilBrown <neilb@xxxxxxx> --- fs/namei.c | 15 +-------------- fs/overlayfs/overlayfs.c | 26 ++------------------------ 2 files changed, 3 insertions(+), 38 deletions(-) diff --git a/fs/namei.c b/fs/namei.c index 6042564..291a839 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -254,22 +254,9 @@ int dentry_permission(struct dentry *dentry, int mask) struct inode *inode = dentry->d_inode; int retval; - if (mask & MAY_WRITE) { - umode_t mode = inode->i_mode; - - /* - * Nobody gets write access to a read-only fs. - */ - if (IS_RDONLY(inode) && - (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode))) - return -EROFS; - - /* - * Nobody gets write access to an immutable file. - */ + if (mask & MAY_WRITE) if (IS_IMMUTABLE(inode)) return -EACCES; - } if (inode->i_op->permission) retval = inode->i_op->permission(dentry, mask); diff --git a/fs/overlayfs/overlayfs.c b/fs/overlayfs/overlayfs.c index cdeafa7..749109a 100644 --- a/fs/overlayfs/overlayfs.c +++ b/fs/overlayfs/overlayfs.c @@ -1127,31 +1127,9 @@ static int ovl_dir_getattr(struct vfsmount *mnt, struct dentry *dentry, static int ovl_permission(struct dentry *dentry, int mask) { struct ovl_entry *ue = dentry->d_fsdata; - struct inode *inode; - int err; - - if (ue->upperpath.dentry) - return dentry_permission(ue->upperpath.dentry, mask); - - inode = ue->lowerpath.dentry->d_inode; - if (!(mask & MAY_WRITE) || special_file(inode->i_mode)) - return dentry_permission(ue->lowerpath.dentry, mask); - - /* Don't check for read-only fs */ - if (mask & MAY_WRITE) { - if (IS_IMMUTABLE(inode)) - return -EACCES; - } - - if (inode->i_op->permission) - err = inode->i_op->permission(ue->lowerpath.dentry, mask); - else - err = generic_permission(inode, mask, inode->i_op->check_acl); - - if (err) - return err; + struct path *realpath = ovl_path(ue); - return security_inode_permission(inode, mask); + return dentry_permission(realpath->dentry, mask); } static int ovl_create_object(struct dentry *dentry, int mode, dev_t rdev, -- To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html