vfs: export check_sticky()
It's already duplicated in btrfs and about to be used in overlayfs too. Move the sticky bit check to an inline helper and call the out-of-line helper only in the unlikly case of the sticky bit being set. Signed-off-by: Miklos Szeredi <mszeredi@suse.cz>
This commit is contained in:
@@ -765,23 +765,6 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* copy of check_sticky in fs/namei.c()
|
||||
* It's inline, so penalty for filesystems that don't use sticky bit is
|
||||
* minimal.
|
||||
*/
|
||||
static inline int btrfs_check_sticky(struct inode *dir, struct inode *inode)
|
||||
{
|
||||
kuid_t fsuid = current_fsuid();
|
||||
|
||||
if (!(dir->i_mode & S_ISVTX))
|
||||
return 0;
|
||||
if (uid_eq(inode->i_uid, fsuid))
|
||||
return 0;
|
||||
if (uid_eq(dir->i_uid, fsuid))
|
||||
return 0;
|
||||
return !capable(CAP_FOWNER);
|
||||
}
|
||||
|
||||
/* copy of may_delete in fs/namei.c()
|
||||
* Check whether we can remove a link victim from directory dir, check
|
||||
* whether the type of victim is right.
|
||||
@@ -817,8 +800,7 @@ static int btrfs_may_delete(struct inode *dir, struct dentry *victim, int isdir)
|
||||
return error;
|
||||
if (IS_APPEND(dir))
|
||||
return -EPERM;
|
||||
if (btrfs_check_sticky(dir, victim->d_inode)||
|
||||
IS_APPEND(victim->d_inode)||
|
||||
if (check_sticky(dir, victim->d_inode) || IS_APPEND(victim->d_inode) ||
|
||||
IS_IMMUTABLE(victim->d_inode) || IS_SWAPFILE(victim->d_inode))
|
||||
return -EPERM;
|
||||
if (isdir) {
|
||||
|
Reference in New Issue
Block a user