Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ceph: Propagate dentry down to inode_change_ok()

To avoid clearing of capabilities or security related extended
attributes too early, inode_change_ok() will need to take dentry instead
of inode. ceph_setattr() has the dentry easily available but
__ceph_setattr() is also called from ceph_set_acl() where dentry is not
easily available. Luckily that call path does not need inode_change_ok()
to be called anyway. So reorganize functions a bit so that
inode_change_ok() is called only from paths where dentry is available.

Reviewed-by: Christoph Hellwig <hch@lst.de>
Acked-by: Jeff Layton <jlayton@redhat.com>
Signed-off-by: Jan Kara <jack@suse.cz>

Jan Kara fd5472ed 69bca807

+16 -8
+5
fs/ceph/acl.c
··· 125 125 goto out_free; 126 126 } 127 127 128 + if (ceph_snap(inode) != CEPH_NOSNAP) { 129 + ret = -EROFS; 130 + goto out_free; 131 + } 132 + 128 133 if (new_mode != old_mode) { 129 134 newattrs.ia_mode = new_mode; 130 135 newattrs.ia_valid = ATTR_MODE;
+11 -8
fs/ceph/inode.c
··· 1905 1905 int inode_dirty_flags = 0; 1906 1906 bool lock_snap_rwsem = false; 1907 1907 1908 - if (ceph_snap(inode) != CEPH_NOSNAP) 1909 - return -EROFS; 1910 - 1911 - err = inode_change_ok(inode, attr); 1912 - if (err != 0) 1913 - return err; 1914 - 1915 1908 prealloc_cf = ceph_alloc_cap_flush(); 1916 1909 if (!prealloc_cf) 1917 1910 return -ENOMEM; ··· 2117 2124 */ 2118 2125 int ceph_setattr(struct dentry *dentry, struct iattr *attr) 2119 2126 { 2120 - return __ceph_setattr(d_inode(dentry), attr); 2127 + struct inode *inode = d_inode(dentry); 2128 + int err; 2129 + 2130 + if (ceph_snap(inode) != CEPH_NOSNAP) 2131 + return -EROFS; 2132 + 2133 + err = inode_change_ok(inode, attr); 2134 + if (err != 0) 2135 + return err; 2136 + 2137 + return __ceph_setattr(inode, attr); 2121 2138 } 2122 2139 2123 2140 /*