From: Jeff Mahoney Here are a few fixes for bugs noticed on reiserfs-list or our own bugzilla. Attached is a patch that fixes several problems with xattrs/acls: [SECURITY] Fixes the inode not getting dirtied when mode is set ~ via setxattr() [CORRECTNESS] Fixes the inode not getting ctime updated when an xattr is ~ removed [DATA] Fixes an issue with dcache hash colliding names in the filesystem ~ root caused by the d_compare to hide .reiserfs_priv. The bug ~ can only occur in the filesystem root, which is why we haven't ~ seen many (any, outside of the suse bugzilla, afaik) reports on ~ this. The results are that dcache operations on colliding entries ~ in the fs root will choose the first match rather than the ~ correct entry. Signed-off-by: Andrew Morton --- 25-akpm/fs/reiserfs/xattr.c | 11 +++++++++-- 25-akpm/fs/reiserfs/xattr_acl.c | 8 +++++++- 2 files changed, 16 insertions(+), 3 deletions(-) diff -puN fs/reiserfs/xattr_acl.c~reiserfs-xattr-acl-fixes fs/reiserfs/xattr_acl.c --- 25/fs/reiserfs/xattr_acl.c~reiserfs-xattr-acl-fixes 2004-08-16 11:42:01.480546208 -0700 +++ 25-akpm/fs/reiserfs/xattr_acl.c 2004-08-16 11:42:01.485545448 -0700 @@ -289,8 +289,14 @@ reiserfs_set_acl(struct inode *inode, in error = reiserfs_xattr_set(inode, name, value, size, 0); } else { error = reiserfs_xattr_del (inode, name); - if (error == -ENODATA) + if (error == -ENODATA) { + /* This may seem odd here, but it means that the ACL was set + * with a value representable with mode bits. If there was + * an ACL before, reiserfs_xattr_del already dirtied the inode. + */ + mark_inode_dirty (inode); error = 0; + } } if (value) diff -puN fs/reiserfs/xattr.c~reiserfs-xattr-acl-fixes fs/reiserfs/xattr.c --- 25/fs/reiserfs/xattr.c~reiserfs-xattr-acl-fixes 2004-08-16 11:42:01.482545904 -0700 +++ 25-akpm/fs/reiserfs/xattr.c 2004-08-16 11:42:01.487545144 -0700 @@ -761,6 +761,11 @@ reiserfs_xattr_del (struct inode *inode, err = __reiserfs_xattr_del (dir, name, strlen (name)); dput (dir); + if (!err) { + inode->i_ctime = CURRENT_TIME; + mark_inode_dirty (inode); + } + out: return err; } @@ -1240,8 +1245,10 @@ xattr_lookup_poison (struct dentry *dent name->hash == priv_root->d_name.hash && !memcmp (name->name, priv_root->d_name.name, name->len)) { return -ENOENT; - } - return 0; + } else if (q1->len == name->len && + !memcmp(q1->name, name->name, name->len)) + return 0; + return 1; } static struct dentry_operations xattr_lookup_poison_ops = { _