Skip to content

Commit

Permalink
fs: Give dentry to inode_change_ok() instead of inode
Browse files Browse the repository at this point in the history
inode_change_ok() will be resposible for clearing capabilities and IMA
extended attributes and as such will need dentry. Give it as an argument
to inode_change_ok() instead of an inode. Also rename inode_change_ok()
to setattr_prepare() to better relect that it does also some
modifications in addition to checks.

Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Jan Kara <jack@suse.cz>
  • Loading branch information
jankara committed Sep 22, 2016
1 parent 6249033 commit 31051c8
Show file tree
Hide file tree
Showing 51 changed files with 67 additions and 68 deletions.
4 changes: 2 additions & 2 deletions Documentation/filesystems/porting
Expand Up @@ -287,8 +287,8 @@ implementing on-disk size changes. Start with a copy of the old inode_setattr
and vmtruncate, and the reorder the vmtruncate + foofs_vmtruncate sequence to
be in order of zeroing blocks using block_truncate_page or similar helpers,
size update and on finally on-disk truncation which should not fail.
inode_change_ok now includes the size checks for ATTR_SIZE and must be called
in the beginning of ->setattr unconditionally.
setattr_prepare (which used to be inode_change_ok) now includes the size checks
for ATTR_SIZE and must be called in the beginning of ->setattr unconditionally.

[mandatory]

Expand Down
2 changes: 1 addition & 1 deletion drivers/staging/lustre/lustre/llite/llite_lib.c
Expand Up @@ -1192,7 +1192,7 @@ int ll_setattr_raw(struct dentry *dentry, struct iattr *attr, bool hsm_import)
attr->ia_valid |= ATTR_MTIME | ATTR_CTIME;
}

/* POSIX: check before ATTR_*TIME_SET set (from inode_change_ok) */
/* POSIX: check before ATTR_*TIME_SET set (from setattr_prepare) */
if (attr->ia_valid & TIMES_SET_FLAGS) {
if ((!uid_eq(current_fsuid(), inode->i_uid)) &&
!capable(CFS_CAP_FOWNER))
Expand Down
2 changes: 1 addition & 1 deletion fs/9p/vfs_inode.c
Expand Up @@ -1094,7 +1094,7 @@ static int v9fs_vfs_setattr(struct dentry *dentry, struct iattr *iattr)
struct p9_wstat wstat;

p9_debug(P9_DEBUG_VFS, "\n");
retval = inode_change_ok(d_inode(dentry), iattr);
retval = setattr_prepare(dentry, iattr);
if (retval)
return retval;

Expand Down
2 changes: 1 addition & 1 deletion fs/9p/vfs_inode_dotl.c
Expand Up @@ -558,7 +558,7 @@ int v9fs_vfs_setattr_dotl(struct dentry *dentry, struct iattr *iattr)

p9_debug(P9_DEBUG_VFS, "\n");

retval = inode_change_ok(inode, iattr);
retval = setattr_prepare(dentry, iattr);
if (retval)
return retval;

Expand Down
2 changes: 1 addition & 1 deletion fs/adfs/inode.c
Expand Up @@ -303,7 +303,7 @@ adfs_notify_change(struct dentry *dentry, struct iattr *attr)
unsigned int ia_valid = attr->ia_valid;
int error;

error = inode_change_ok(inode, attr);
error = setattr_prepare(dentry, attr);

/*
* we can't change the UID or GID of any file -
Expand Down
2 changes: 1 addition & 1 deletion fs/affs/inode.c
Expand Up @@ -219,7 +219,7 @@ affs_notify_change(struct dentry *dentry, struct iattr *attr)

pr_debug("notify_change(%lu,0x%x)\n", inode->i_ino, attr->ia_valid);

error = inode_change_ok(inode,attr);
error = setattr_prepare(dentry, attr);
if (error)
goto out;

Expand Down
15 changes: 9 additions & 6 deletions fs/attr.c
Expand Up @@ -17,19 +17,22 @@
#include <linux/ima.h>

/**
* inode_change_ok - check if attribute changes to an inode are allowed
* @inode: inode to check
* setattr_prepare - check if attribute changes to a dentry are allowed
* @dentry: dentry to check
* @attr: attributes to change
*
* Check if we are allowed to change the attributes contained in @attr
* in the given inode. This includes the normal unix access permission
* checks, as well as checks for rlimits and others.
* in the given dentry. This includes the normal unix access permission
* checks, as well as checks for rlimits and others. The function also clears
* SGID bit from mode if user is not allowed to set it. Also file capabilities
* and IMA extended attributes are cleared if ATTR_KILL_PRIV is set.
*
* Should be called as the first thing in ->setattr implementations,
* possibly after taking additional locks.
*/
int inode_change_ok(const struct inode *inode, struct iattr *attr)
int setattr_prepare(struct dentry *dentry, struct iattr *attr)
{
struct inode *inode = d_inode(dentry);
unsigned int ia_valid = attr->ia_valid;

/*
Expand Down Expand Up @@ -79,7 +82,7 @@ int inode_change_ok(const struct inode *inode, struct iattr *attr)

return 0;
}
EXPORT_SYMBOL(inode_change_ok);
EXPORT_SYMBOL(setattr_prepare);

/**
* inode_newsize_ok - may this inode be truncated to a given size
Expand Down
2 changes: 1 addition & 1 deletion fs/btrfs/inode.c
Expand Up @@ -5042,7 +5042,7 @@ static int btrfs_setattr(struct dentry *dentry, struct iattr *attr)
if (btrfs_root_readonly(root))
return -EROFS;

err = inode_change_ok(inode, attr);
err = setattr_prepare(dentry, attr);
if (err)
return err;

Expand Down
2 changes: 1 addition & 1 deletion fs/ceph/inode.c
Expand Up @@ -2123,7 +2123,7 @@ int ceph_setattr(struct dentry *dentry, struct iattr *attr)
if (ceph_snap(inode) != CEPH_NOSNAP)
return -EROFS;

err = inode_change_ok(inode, attr);
err = setattr_prepare(dentry, attr);
if (err != 0)
return err;

Expand Down
4 changes: 2 additions & 2 deletions fs/cifs/inode.c
Expand Up @@ -2154,7 +2154,7 @@ cifs_setattr_unix(struct dentry *direntry, struct iattr *attrs)
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM)
attrs->ia_valid |= ATTR_FORCE;

rc = inode_change_ok(inode, attrs);
rc = setattr_prepare(direntry, attrs);
if (rc < 0)
goto out;

Expand Down Expand Up @@ -2294,7 +2294,7 @@ cifs_setattr_nounix(struct dentry *direntry, struct iattr *attrs)
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM)
attrs->ia_valid |= ATTR_FORCE;

rc = inode_change_ok(inode, attrs);
rc = setattr_prepare(direntry, attrs);
if (rc < 0) {
free_xid(xid);
return rc;
Expand Down
2 changes: 1 addition & 1 deletion fs/ecryptfs/inode.c
Expand Up @@ -927,7 +927,7 @@ static int ecryptfs_setattr(struct dentry *dentry, struct iattr *ia)
}
mutex_unlock(&crypt_stat->cs_mutex);

rc = inode_change_ok(inode, ia);
rc = setattr_prepare(dentry, ia);
if (rc)
goto out;
if (ia->ia_valid & ATTR_SIZE) {
Expand Down
2 changes: 1 addition & 1 deletion fs/exofs/inode.c
Expand Up @@ -1034,7 +1034,7 @@ int exofs_setattr(struct dentry *dentry, struct iattr *iattr)
if (unlikely(error))
return error;

error = inode_change_ok(inode, iattr);
error = setattr_prepare(dentry, iattr);
if (unlikely(error))
return error;

Expand Down
2 changes: 1 addition & 1 deletion fs/ext2/inode.c
Expand Up @@ -1580,7 +1580,7 @@ int ext2_setattr(struct dentry *dentry, struct iattr *iattr)
struct inode *inode = d_inode(dentry);
int error;

error = inode_change_ok(inode, iattr);
error = setattr_prepare(dentry, iattr);
if (error)
return error;

Expand Down
2 changes: 1 addition & 1 deletion fs/ext4/inode.c
Expand Up @@ -5073,7 +5073,7 @@ int ext4_setattr(struct dentry *dentry, struct iattr *attr)
int orphan = 0;
const unsigned int ia_valid = attr->ia_valid;

error = inode_change_ok(inode, attr);
error = setattr_prepare(dentry, attr);
if (error)
return error;

Expand Down
2 changes: 1 addition & 1 deletion fs/f2fs/file.c
Expand Up @@ -680,7 +680,7 @@ int f2fs_setattr(struct dentry *dentry, struct iattr *attr)
struct inode *inode = d_inode(dentry);
int err;

err = inode_change_ok(inode, attr);
err = setattr_prepare(dentry, attr);
if (err)
return err;

Expand Down
2 changes: 1 addition & 1 deletion fs/fat/file.c
Expand Up @@ -450,7 +450,7 @@ int fat_setattr(struct dentry *dentry, struct iattr *attr)
attr->ia_valid &= ~TIMES_SET_FLAGS;
}

error = inode_change_ok(inode, attr);
error = setattr_prepare(dentry, attr);
attr->ia_valid = ia_valid;
if (error) {
if (sbi->options.quiet)
Expand Down
2 changes: 1 addition & 1 deletion fs/fuse/dir.c
Expand Up @@ -1609,7 +1609,7 @@ int fuse_do_setattr(struct dentry *dentry, struct iattr *attr,
if (!(fc->flags & FUSE_DEFAULT_PERMISSIONS))
attr->ia_valid |= ATTR_FORCE;

err = inode_change_ok(inode, attr);
err = setattr_prepare(dentry, attr);
if (err)
return err;

Expand Down
2 changes: 1 addition & 1 deletion fs/gfs2/inode.c
Expand Up @@ -1932,7 +1932,7 @@ static int gfs2_setattr(struct dentry *dentry, struct iattr *attr)
if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
goto out;

error = inode_change_ok(inode, attr);
error = setattr_prepare(dentry, attr);
if (error)
goto out;

Expand Down
2 changes: 1 addition & 1 deletion fs/hfs/inode.c
Expand Up @@ -605,7 +605,7 @@ int hfs_inode_setattr(struct dentry *dentry, struct iattr * attr)
struct hfs_sb_info *hsb = HFS_SB(inode->i_sb);
int error;

error = inode_change_ok(inode, attr); /* basic permission checks */
error = setattr_prepare(dentry, attr); /* basic permission checks */
if (error)
return error;

Expand Down
2 changes: 1 addition & 1 deletion fs/hfsplus/inode.c
Expand Up @@ -245,7 +245,7 @@ static int hfsplus_setattr(struct dentry *dentry, struct iattr *attr)
struct inode *inode = d_inode(dentry);
int error;

error = inode_change_ok(inode, attr);
error = setattr_prepare(dentry, attr);
if (error)
return error;

Expand Down
2 changes: 1 addition & 1 deletion fs/hostfs/hostfs_kern.c
Expand Up @@ -812,7 +812,7 @@ static int hostfs_setattr(struct dentry *dentry, struct iattr *attr)

int fd = HOSTFS_I(inode)->fd;

err = inode_change_ok(inode, attr);
err = setattr_prepare(dentry, attr);
if (err)
return err;

Expand Down
2 changes: 1 addition & 1 deletion fs/hpfs/inode.c
Expand Up @@ -273,7 +273,7 @@ int hpfs_setattr(struct dentry *dentry, struct iattr *attr)
if ((attr->ia_valid & ATTR_SIZE) && attr->ia_size > inode->i_size)
goto out_unlock;

error = inode_change_ok(inode, attr);
error = setattr_prepare(dentry, attr);
if (error)
goto out_unlock;

Expand Down
2 changes: 1 addition & 1 deletion fs/hugetlbfs/inode.c
Expand Up @@ -672,7 +672,7 @@ static int hugetlbfs_setattr(struct dentry *dentry, struct iattr *attr)

BUG_ON(!inode);

error = inode_change_ok(inode, attr);
error = setattr_prepare(dentry, attr);
if (error)
return error;

Expand Down
2 changes: 1 addition & 1 deletion fs/jffs2/fs.c
Expand Up @@ -193,7 +193,7 @@ int jffs2_setattr(struct dentry *dentry, struct iattr *iattr)
struct inode *inode = d_inode(dentry);
int rc;

rc = inode_change_ok(inode, iattr);
rc = setattr_prepare(dentry, iattr);
if (rc)
return rc;

Expand Down
2 changes: 1 addition & 1 deletion fs/jfs/file.c
Expand Up @@ -103,7 +103,7 @@ int jfs_setattr(struct dentry *dentry, struct iattr *iattr)
struct inode *inode = d_inode(dentry);
int rc;

rc = inode_change_ok(inode, iattr);
rc = setattr_prepare(dentry, iattr);
if (rc)
return rc;

Expand Down
2 changes: 1 addition & 1 deletion fs/kernfs/inode.c
Expand Up @@ -122,7 +122,7 @@ int kernfs_iop_setattr(struct dentry *dentry, struct iattr *iattr)
return -EINVAL;

mutex_lock(&kernfs_mutex);
error = inode_change_ok(inode, iattr);
error = setattr_prepare(dentry, iattr);
if (error)
goto out;

Expand Down
2 changes: 1 addition & 1 deletion fs/libfs.c
Expand Up @@ -394,7 +394,7 @@ int simple_setattr(struct dentry *dentry, struct iattr *iattr)
struct inode *inode = d_inode(dentry);
int error;

error = inode_change_ok(inode, iattr);
error = setattr_prepare(dentry, iattr);
if (error)
return error;

Expand Down
2 changes: 1 addition & 1 deletion fs/logfs/file.c
Expand Up @@ -244,7 +244,7 @@ static int logfs_setattr(struct dentry *dentry, struct iattr *attr)
struct inode *inode = d_inode(dentry);
int err = 0;

err = inode_change_ok(inode, attr);
err = setattr_prepare(dentry, attr);
if (err)
return err;

Expand Down
2 changes: 1 addition & 1 deletion fs/minix/file.c
Expand Up @@ -26,7 +26,7 @@ static int minix_setattr(struct dentry *dentry, struct iattr *attr)
struct inode *inode = d_inode(dentry);
int error;

error = inode_change_ok(inode, attr);
error = setattr_prepare(dentry, attr);
if (error)
return error;

Expand Down
2 changes: 1 addition & 1 deletion fs/ncpfs/inode.c
Expand Up @@ -884,7 +884,7 @@ int ncp_notify_change(struct dentry *dentry, struct iattr *attr)
/* ageing the dentry to force validation */
ncp_age_dentry(server, dentry);

result = inode_change_ok(inode, attr);
result = setattr_prepare(dentry, attr);
if (result < 0)
goto out;

Expand Down
8 changes: 3 additions & 5 deletions fs/nfsd/nfsproc.c
Expand Up @@ -74,10 +74,10 @@ nfsd_proc_setattr(struct svc_rqst *rqstp, struct nfsd_sattrargs *argp,
* which only requires access, and "set-[ac]time-to-X" which
* requires ownership.
* So if it looks like it might be "set both to the same time which
* is close to now", and if inode_change_ok fails, then we
* is close to now", and if setattr_prepare fails, then we
* convert to "set to now" instead of "set to explicit time"
*
* We only call inode_change_ok as the last test as technically
* We only call setattr_prepare as the last test as technically
* it is not an interface that we should be using.
*/
#define BOTH_TIME_SET (ATTR_ATIME_SET | ATTR_MTIME_SET)
Expand All @@ -92,17 +92,15 @@ nfsd_proc_setattr(struct svc_rqst *rqstp, struct nfsd_sattrargs *argp,
* request is. We require it be within 30 minutes of now.
*/
time_t delta = iap->ia_atime.tv_sec - get_seconds();
struct inode *inode;

nfserr = fh_verify(rqstp, fhp, 0, NFSD_MAY_NOP);
if (nfserr)
goto done;
inode = d_inode(fhp->fh_dentry);

if (delta < 0)
delta = -delta;
if (delta < MAX_TOUCH_TIME_ERROR &&
inode_change_ok(inode, iap) != 0) {
setattr_prepare(fhp->fh_dentry, iap) != 0) {
/*
* Turn off ATTR_[AM]TIME_SET but leave ATTR_[AM]TIME.
* This will cause notify_change to set these times
Expand Down
2 changes: 1 addition & 1 deletion fs/nilfs2/inode.c
Expand Up @@ -829,7 +829,7 @@ int nilfs_setattr(struct dentry *dentry, struct iattr *iattr)
struct super_block *sb = inode->i_sb;
int err;

err = inode_change_ok(inode, iattr);
err = setattr_prepare(dentry, iattr);
if (err)
return err;

Expand Down
2 changes: 1 addition & 1 deletion fs/ntfs/inode.c
Expand Up @@ -2893,7 +2893,7 @@ int ntfs_setattr(struct dentry *dentry, struct iattr *attr)
int err;
unsigned int ia_valid = attr->ia_valid;

err = inode_change_ok(vi, attr);
err = setattr_prepare(dentry, attr);
if (err)
goto out;
/* We do not support NTFS ACLs yet. */
Expand Down
2 changes: 1 addition & 1 deletion fs/ocfs2/dlmfs/dlmfs.c
Expand Up @@ -211,7 +211,7 @@ static int dlmfs_file_setattr(struct dentry *dentry, struct iattr *attr)
struct inode *inode = d_inode(dentry);

attr->ia_valid &= ~ATTR_SIZE;
error = inode_change_ok(inode, attr);
error = setattr_prepare(dentry, attr);
if (error)
return error;

Expand Down
2 changes: 1 addition & 1 deletion fs/ocfs2/file.c
Expand Up @@ -1155,7 +1155,7 @@ int ocfs2_setattr(struct dentry *dentry, struct iattr *attr)
if (!(attr->ia_valid & OCFS2_VALID_ATTRS))
return 0;

status = inode_change_ok(inode, attr);
status = setattr_prepare(dentry, attr);
if (status)
return status;

Expand Down
2 changes: 1 addition & 1 deletion fs/omfs/file.c
Expand Up @@ -349,7 +349,7 @@ static int omfs_setattr(struct dentry *dentry, struct iattr *attr)
struct inode *inode = d_inode(dentry);
int error;

error = inode_change_ok(inode, attr);
error = setattr_prepare(dentry, attr);
if (error)
return error;

Expand Down
2 changes: 1 addition & 1 deletion fs/orangefs/inode.c
Expand Up @@ -219,7 +219,7 @@ int orangefs_setattr(struct dentry *dentry, struct iattr *iattr)
"orangefs_setattr: called on %s\n",
dentry->d_name.name);

ret = inode_change_ok(inode, iattr);
ret = setattr_prepare(dentry, iattr);
if (ret)
goto out;

Expand Down

0 comments on commit 31051c8

Please sign in to comment.