* This is a variant of fs/namei.c:permission() or inode_permission() which
* skips over EROFS tests (because we perform copyup on EROFS).
*/
-static int __inode_permission(struct inode *inode, int mask)
+static int __inode_permission(struct inode *inode, int mask, unsigned int flags)
{
int retval;
/* Ordinary permission routines do not understand MAY_APPEND. */
if (inode->i_op && inode->i_op->permission) {
- retval = inode->i_op->permission(inode, mask);
+ retval = inode->i_op->permission(inode, mask, flags);
if (!retval) {
/*
* Exec permission on a regular file is denied if none
return -EACCES;
}
} else {
- retval = generic_permission(inode, mask, NULL);
+ retval = generic_permission(inode, mask, flags, NULL);
}
if (retval)
return retval;
* unionfs_permission, or anything it calls, will use stale branch
* information.
*/
-static int unionfs_permission(struct inode *inode, int mask)
+static int unionfs_permission(struct inode *inode, int mask, unsigned int flags)
{
struct inode *lower_inode = NULL;
int err = 0;
struct inode *inode_grabbed = igrab(inode);
struct dentry *dentry = d_find_alias(inode);
+ if (flags & IPERM_FLAG_RCU)
+ return -ECHILD;
+
if (dentry)
unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD);
* copyup taking place later on. However, if user never had
* access to the file, then no copyup could ever take place.
*/
- err = __inode_permission(lower_inode, mask);
+ err = __inode_permission(lower_inode, mask, flags);
if (err && err != -EACCES && err != EPERM && bindex > 0) {
umode_t mode = lower_inode->i_mode;
if ((is_robranch_super(inode->i_sb, bindex) ||
if (err && err == -EACCES &&
is_robranch_super(inode->i_sb, bindex) &&
lower_inode->i_sb->s_magic == NFS_SUPER_MAGIC)
- err = generic_permission(lower_inode, mask, NULL);
+ err = generic_permission(lower_inode, mask, flags, NULL);
/*
* The permissions are an intersection of the overall directory