Unverified Commit d9f892b9 authored by Christian Brauner's avatar Christian Brauner Committed by Christian Brauner (Microsoft)
Browse files

reiserfs: rework priv inode handling



Reiserfs is the only filesystem that removes IOP_XATTR without also
using a set of dedicated inode operations at the same time that nop all
xattr related inode operations. This means we need to have a IOP_XATTR
check in vfs_listxattr() instead of just being able to check for
->listxatt() being implemented.

Introduce a dedicated set of nop inode operations that are used when
IOP_XATTR is removed, allowing us to remove that check from
vfs_listxattr(). This in turn allows us to completely decouple POSIX ACLs from
IOP_XATTR.

Cc: reiserfs-devel@vger.kernel.org
Signed-off-by: default avatarChristian Brauner (Microsoft) <brauner@kernel.org>
parent d549b741
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -261,3 +261,10 @@ const struct inode_operations reiserfs_file_inode_operations = {
	.fileattr_get = reiserfs_fileattr_get,
	.fileattr_set = reiserfs_fileattr_set,
};

const struct inode_operations reiserfs_priv_file_inode_operations = {
	.setattr = reiserfs_setattr,
	.permission = reiserfs_permission,
	.fileattr_get = reiserfs_fileattr_get,
	.fileattr_set = reiserfs_fileattr_set,
};
+2 −4
Original line number Diff line number Diff line
@@ -2087,10 +2087,8 @@ int reiserfs_new_inode(struct reiserfs_transaction_handle *th,
	 * Mark it private if we're creating the privroot
	 * or something under it.
	 */
	if (IS_PRIVATE(dir) || dentry == REISERFS_SB(sb)->priv_root) {
		inode->i_flags |= S_PRIVATE;
		inode->i_opflags &= ~IOP_XATTR;
	}
	if (IS_PRIVATE(dir) || dentry == REISERFS_SB(sb)->priv_root)
		reiserfs_init_priv_inode(inode);

	if (reiserfs_posixacl(inode->i_sb)) {
		reiserfs_write_unlock(inode->i_sb);
+45 −5
Original line number Diff line number Diff line
@@ -378,13 +378,11 @@ static struct dentry *reiserfs_lookup(struct inode *dir, struct dentry *dentry,

		/*
		 * Propagate the private flag so we know we're
		 * in the priv tree.  Also clear IOP_XATTR
		 * in the priv tree.  Also clear xattr support
		 * since we don't have xattrs on xattr files.
		 */
		if (IS_PRIVATE(dir)) {
			inode->i_flags |= S_PRIVATE;
			inode->i_opflags &= ~IOP_XATTR;
		}
		if (IS_PRIVATE(dir))
			reiserfs_init_priv_inode(inode);
	}
	reiserfs_write_unlock(dir->i_sb);
	if (retval == IO_ERROR) {
@@ -1649,6 +1647,48 @@ static int reiserfs_rename(struct mnt_idmap *idmap,
	return retval;
}

static const struct inode_operations reiserfs_priv_dir_inode_operations = {
	.create = reiserfs_create,
	.lookup = reiserfs_lookup,
	.link = reiserfs_link,
	.unlink = reiserfs_unlink,
	.symlink = reiserfs_symlink,
	.mkdir = reiserfs_mkdir,
	.rmdir = reiserfs_rmdir,
	.mknod = reiserfs_mknod,
	.rename = reiserfs_rename,
	.setattr = reiserfs_setattr,
	.permission = reiserfs_permission,
	.fileattr_get = reiserfs_fileattr_get,
	.fileattr_set = reiserfs_fileattr_set,
};

static const struct inode_operations reiserfs_priv_symlink_inode_operations = {
	.get_link	= page_get_link,
	.setattr = reiserfs_setattr,
	.permission = reiserfs_permission,
};

static const struct inode_operations reiserfs_priv_special_inode_operations = {
	.setattr = reiserfs_setattr,
	.permission = reiserfs_permission,
};

void reiserfs_init_priv_inode(struct inode *inode)
{
	inode->i_flags |= S_PRIVATE;
	inode->i_opflags &= ~IOP_XATTR;

	if (S_ISREG(inode->i_mode))
		inode->i_op = &reiserfs_priv_file_inode_operations;
	else if (S_ISDIR(inode->i_mode))
		inode->i_op = &reiserfs_priv_dir_inode_operations;
	else if (S_ISLNK(inode->i_mode))
		inode->i_op = &reiserfs_priv_symlink_inode_operations;
	else
		inode->i_op = &reiserfs_priv_special_inode_operations;
}

/* directories can handle most operations...  */
const struct inode_operations reiserfs_dir_inode_operations = {
	.create = reiserfs_create,
+2 −0
Original line number Diff line number Diff line
@@ -3106,6 +3106,7 @@ int reiserfs_setattr(struct mnt_idmap *idmap, struct dentry *dentry,
int __reiserfs_write_begin(struct page *page, unsigned from, unsigned len);

/* namei.c */
void reiserfs_init_priv_inode(struct inode *inode);
void set_de_name_and_namelen(struct reiserfs_dir_entry *de);
int search_by_entry_key(struct super_block *sb, const struct cpu_key *key,
			struct treepath *path, struct reiserfs_dir_entry *de);
@@ -3175,6 +3176,7 @@ void reiserfs_unmap_buffer(struct buffer_head *);

/* file.c */
extern const struct inode_operations reiserfs_file_inode_operations;
extern const struct inode_operations reiserfs_priv_file_inode_operations;
extern const struct file_operations reiserfs_file_operations;
extern const struct address_space_operations reiserfs_address_space_operations;

+3 −6
Original line number Diff line number Diff line
@@ -896,8 +896,7 @@ static int create_privroot(struct dentry *dentry)
		return -EOPNOTSUPP;
	}

	d_inode(dentry)->i_flags |= S_PRIVATE;
	d_inode(dentry)->i_opflags &= ~IOP_XATTR;
	reiserfs_init_priv_inode(d_inode(dentry));
	reiserfs_info(dentry->d_sb, "Created %s - reserved for xattr "
		      "storage.\n", PRIVROOT_NAME);

@@ -979,10 +978,8 @@ int reiserfs_lookup_privroot(struct super_block *s)
	if (!IS_ERR(dentry)) {
		REISERFS_SB(s)->priv_root = dentry;
		d_set_d_op(dentry, &xattr_lookup_poison_ops);
		if (d_really_is_positive(dentry)) {
			d_inode(dentry)->i_flags |= S_PRIVATE;
			d_inode(dentry)->i_opflags &= ~IOP_XATTR;
		}
		if (d_really_is_positive(dentry))
			reiserfs_init_priv_inode(d_inode(dentry));
	} else
		err = PTR_ERR(dentry);
	inode_unlock(d_inode(s->s_root));