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

reiserfs: fix extended attributes on the root directory

Since commit d0a5b995a308 (vfs: Add IOP_XATTR inode operations flag)
extended attributes haven't worked on the root directory in reiserfs.

This is due to reiserfs conditionally setting the sb->s_xattrs handler
array depending on whether it located or create the internal privroot
directory. It necessarily does this after the root inode is already
read in. The IOP_XATTR flag is set during inode initialization, so
it never gets set on the root directory.

This commit unconditionally assigns sb->s_xattrs and clears IOP_XATTR on
internal inodes. The old return values due to the conditional assignment
are handled via open_xa_root, which now returns EOPNOTSUPP as the VFS
would have done.

Link: https://lore.kernel.org/r/20191024143127.17509-1-jeffm@suse.com
CC: stable@vger.kernel.org
Fixes: d0a5b995a308 ("vfs: Add IOP_XATTR inode operations flag")
Signed-off-by: Jeff Mahoney <jeffm@suse.com>
Signed-off-by: Jan Kara <jack@suse.cz>

authored by

Jeff Mahoney and committed by
Jan Kara
60e4cf67 acd1f046

+32 -14
+10 -2
fs/reiserfs/inode.c
··· 2097 2097 goto out_inserted_sd; 2098 2098 } 2099 2099 2100 + /* 2101 + * Mark it private if we're creating the privroot 2102 + * or something under it. 2103 + */ 2104 + if (IS_PRIVATE(dir) || dentry == REISERFS_SB(sb)->priv_root) { 2105 + inode->i_flags |= S_PRIVATE; 2106 + inode->i_opflags &= ~IOP_XATTR; 2107 + } 2108 + 2100 2109 if (reiserfs_posixacl(inode->i_sb)) { 2101 2110 reiserfs_write_unlock(inode->i_sb); 2102 2111 retval = reiserfs_inherit_default_acl(th, dir, dentry, inode); ··· 2120 2111 reiserfs_warning(inode->i_sb, "jdm-13090", 2121 2112 "ACLs aren't enabled in the fs, " 2122 2113 "but vfs thinks they are!"); 2123 - } else if (IS_PRIVATE(dir)) 2124 - inode->i_flags |= S_PRIVATE; 2114 + } 2125 2115 2126 2116 if (security->name) { 2127 2117 reiserfs_write_unlock(inode->i_sb);
+5 -2
fs/reiserfs/namei.c
··· 377 377 378 378 /* 379 379 * Propagate the private flag so we know we're 380 - * in the priv tree 380 + * in the priv tree. Also clear IOP_XATTR 381 + * since we don't have xattrs on xattr files. 381 382 */ 382 - if (IS_PRIVATE(dir)) 383 + if (IS_PRIVATE(dir)) { 383 384 inode->i_flags |= S_PRIVATE; 385 + inode->i_opflags &= ~IOP_XATTR; 386 + } 384 387 } 385 388 reiserfs_write_unlock(dir->i_sb); 386 389 if (retval == IO_ERROR) {
+2
fs/reiserfs/reiserfs.h
··· 1168 1168 return bmap_nr > ((1LL << 16) - 1); 1169 1169 } 1170 1170 1171 + extern const struct xattr_handler *reiserfs_xattr_handlers[]; 1172 + 1171 1173 /* 1172 1174 * this says about version of key of all items (but stat data) the 1173 1175 * object consists of
+2
fs/reiserfs/super.c
··· 2049 2049 if (replay_only(s)) 2050 2050 goto error_unlocked; 2051 2051 2052 + s->s_xattr = reiserfs_xattr_handlers; 2053 + 2052 2054 if (bdev_read_only(s->s_bdev) && !sb_rdonly(s)) { 2053 2055 SWARN(silent, s, "clm-7000", 2054 2056 "Detected readonly device, marking FS readonly");
+12 -7
fs/reiserfs/xattr.c
··· 122 122 struct dentry *xaroot; 123 123 124 124 if (d_really_is_negative(privroot)) 125 - return ERR_PTR(-ENODATA); 125 + return ERR_PTR(-EOPNOTSUPP); 126 126 127 127 inode_lock_nested(d_inode(privroot), I_MUTEX_XATTR); 128 128 129 129 xaroot = dget(REISERFS_SB(sb)->xattr_root); 130 130 if (!xaroot) 131 - xaroot = ERR_PTR(-ENODATA); 131 + xaroot = ERR_PTR(-EOPNOTSUPP); 132 132 else if (d_really_is_negative(xaroot)) { 133 133 int err = -ENODATA; 134 134 ··· 619 619 int error, error2; 620 620 size_t jbegin_count = reiserfs_xattr_nblocks(inode, buffer_size); 621 621 622 + /* Check before we start a transaction and then do nothing. */ 623 + if (!d_really_is_positive(REISERFS_SB(inode->i_sb)->priv_root)) 624 + return -EOPNOTSUPP; 625 + 622 626 if (!(flags & XATTR_REPLACE)) 623 627 jbegin_count += reiserfs_xattr_jcreate_nblocks(inode); 624 628 ··· 845 841 if (d_really_is_negative(dentry)) 846 842 return -EINVAL; 847 843 848 - if (!dentry->d_sb->s_xattr || 849 - get_inode_sd_version(d_inode(dentry)) == STAT_DATA_V1) 844 + if (get_inode_sd_version(d_inode(dentry)) == STAT_DATA_V1) 850 845 return -EOPNOTSUPP; 851 846 852 847 dir = open_xa_dir(d_inode(dentry), XATTR_REPLACE); ··· 885 882 } 886 883 887 884 d_inode(dentry)->i_flags |= S_PRIVATE; 885 + d_inode(dentry)->i_opflags &= ~IOP_XATTR; 888 886 reiserfs_info(dentry->d_sb, "Created %s - reserved for xattr " 889 887 "storage.\n", PRIVROOT_NAME); 890 888 ··· 899 895 #endif 900 896 901 897 /* Actual operations that are exported to VFS-land */ 902 - static const struct xattr_handler *reiserfs_xattr_handlers[] = { 898 + const struct xattr_handler *reiserfs_xattr_handlers[] = { 903 899 #ifdef CONFIG_REISERFS_FS_XATTR 904 900 &reiserfs_xattr_user_handler, 905 901 &reiserfs_xattr_trusted_handler, ··· 970 966 if (!IS_ERR(dentry)) { 971 967 REISERFS_SB(s)->priv_root = dentry; 972 968 d_set_d_op(dentry, &xattr_lookup_poison_ops); 973 - if (d_really_is_positive(dentry)) 969 + if (d_really_is_positive(dentry)) { 974 970 d_inode(dentry)->i_flags |= S_PRIVATE; 971 + d_inode(dentry)->i_opflags &= ~IOP_XATTR; 972 + } 975 973 } else 976 974 err = PTR_ERR(dentry); 977 975 inode_unlock(d_inode(s->s_root)); ··· 1002 996 } 1003 997 1004 998 if (d_really_is_positive(privroot)) { 1005 - s->s_xattr = reiserfs_xattr_handlers; 1006 999 inode_lock(d_inode(privroot)); 1007 1000 if (!REISERFS_SB(s)->xattr_root) { 1008 1001 struct dentry *dentry;
+1 -3
fs/reiserfs/xattr_acl.c
··· 320 320 * would be useless since permissions are ignored, and a pain because 321 321 * it introduces locking cycles 322 322 */ 323 - if (IS_PRIVATE(dir)) { 324 - inode->i_flags |= S_PRIVATE; 323 + if (IS_PRIVATE(inode)) 325 324 goto apply_umask; 326 - } 327 325 328 326 err = posix_acl_create(dir, &inode->i_mode, &default_acl, &acl); 329 327 if (err)