Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 41be8bed authored by Christoph Hellwig's avatar Christoph Hellwig Committed by Lachlan McIlroy
Browse files

[XFS] sanitize xfs_initialize_vnode



Sanitize setting up the Linux indode.

Setting up the xfs_inode <-> inode link is opencoded in xfs_iget_core now
because that's the only place it needs to be done, xfs_initialize_vnode is
renamed to xfs_setup_inode and loses all superflous paramaters. The check
for I_NEW is removed because it always is true and the di_mode check moves
into xfs_iget_core because it's only needed there.

xfs_set_inodeops and xfs_revalidate_inode are merged into xfs_setup_inode
and the whole things is moved into xfs_iops.c where it belongs.

SGI-PV: 981498

SGI-Modid: xfs-linux-melb:xfs-kern:31782a

Signed-off-by: default avatarChristoph Hellwig <hch@infradead.org>
Signed-off-by: default avatarNiv Sardi <xaiki@sgi.com>
Signed-off-by: default avatarLachlan McIlroy <lachlan@sgi.com>
parent 5ec7f8c7
Loading
Loading
Loading
Loading
+99 −4
Original line number Original line Diff line number Diff line
@@ -710,7 +710,7 @@ out_error:
	return error;
	return error;
}
}


const struct inode_operations xfs_inode_operations = {
static const struct inode_operations xfs_inode_operations = {
	.permission		= xfs_vn_permission,
	.permission		= xfs_vn_permission,
	.truncate		= xfs_vn_truncate,
	.truncate		= xfs_vn_truncate,
	.getattr		= xfs_vn_getattr,
	.getattr		= xfs_vn_getattr,
@@ -722,7 +722,7 @@ const struct inode_operations xfs_inode_operations = {
	.fallocate		= xfs_vn_fallocate,
	.fallocate		= xfs_vn_fallocate,
};
};


const struct inode_operations xfs_dir_inode_operations = {
static const struct inode_operations xfs_dir_inode_operations = {
	.create			= xfs_vn_create,
	.create			= xfs_vn_create,
	.lookup			= xfs_vn_lookup,
	.lookup			= xfs_vn_lookup,
	.link			= xfs_vn_link,
	.link			= xfs_vn_link,
@@ -747,7 +747,7 @@ const struct inode_operations xfs_dir_inode_operations = {
	.listxattr		= xfs_vn_listxattr,
	.listxattr		= xfs_vn_listxattr,
};
};


const struct inode_operations xfs_dir_ci_inode_operations = {
static const struct inode_operations xfs_dir_ci_inode_operations = {
	.create			= xfs_vn_create,
	.create			= xfs_vn_create,
	.lookup			= xfs_vn_ci_lookup,
	.lookup			= xfs_vn_ci_lookup,
	.link			= xfs_vn_link,
	.link			= xfs_vn_link,
@@ -772,7 +772,7 @@ const struct inode_operations xfs_dir_ci_inode_operations = {
	.listxattr		= xfs_vn_listxattr,
	.listxattr		= xfs_vn_listxattr,
};
};


const struct inode_operations xfs_symlink_inode_operations = {
static const struct inode_operations xfs_symlink_inode_operations = {
	.readlink		= generic_readlink,
	.readlink		= generic_readlink,
	.follow_link		= xfs_vn_follow_link,
	.follow_link		= xfs_vn_follow_link,
	.put_link		= xfs_vn_put_link,
	.put_link		= xfs_vn_put_link,
@@ -784,3 +784,98 @@ const struct inode_operations xfs_symlink_inode_operations = {
	.removexattr		= generic_removexattr,
	.removexattr		= generic_removexattr,
	.listxattr		= xfs_vn_listxattr,
	.listxattr		= xfs_vn_listxattr,
};
};

STATIC void
xfs_diflags_to_iflags(
	struct inode		*inode,
	struct xfs_inode	*ip)
{
	if (ip->i_d.di_flags & XFS_DIFLAG_IMMUTABLE)
		inode->i_flags |= S_IMMUTABLE;
	else
		inode->i_flags &= ~S_IMMUTABLE;
	if (ip->i_d.di_flags & XFS_DIFLAG_APPEND)
		inode->i_flags |= S_APPEND;
	else
		inode->i_flags &= ~S_APPEND;
	if (ip->i_d.di_flags & XFS_DIFLAG_SYNC)
		inode->i_flags |= S_SYNC;
	else
		inode->i_flags &= ~S_SYNC;
	if (ip->i_d.di_flags & XFS_DIFLAG_NOATIME)
		inode->i_flags |= S_NOATIME;
	else
		inode->i_flags &= ~S_NOATIME;
}

/*
 * Initialize the Linux inode, set up the operation vectors and
 * unlock the inode.
 *
 * When reading existing inodes from disk this is called directly
 * from xfs_iget, when creating a new inode it is called from
 * xfs_ialloc after setting up the inode.
 */
void
xfs_setup_inode(
	struct xfs_inode	*ip)
{
	struct inode		*inode = ip->i_vnode;

	inode->i_mode	= ip->i_d.di_mode;
	inode->i_nlink	= ip->i_d.di_nlink;
	inode->i_uid	= ip->i_d.di_uid;
	inode->i_gid	= ip->i_d.di_gid;

	switch (inode->i_mode & S_IFMT) {
	case S_IFBLK:
	case S_IFCHR:
		inode->i_rdev =
			MKDEV(sysv_major(ip->i_df.if_u2.if_rdev) & 0x1ff,
			      sysv_minor(ip->i_df.if_u2.if_rdev));
		break;
	default:
		inode->i_rdev = 0;
		break;
	}

	inode->i_generation = ip->i_d.di_gen;
	i_size_write(inode, ip->i_d.di_size);
	inode->i_atime.tv_sec	= ip->i_d.di_atime.t_sec;
	inode->i_atime.tv_nsec	= ip->i_d.di_atime.t_nsec;
	inode->i_mtime.tv_sec	= ip->i_d.di_mtime.t_sec;
	inode->i_mtime.tv_nsec	= ip->i_d.di_mtime.t_nsec;
	inode->i_ctime.tv_sec	= ip->i_d.di_ctime.t_sec;
	inode->i_ctime.tv_nsec	= ip->i_d.di_ctime.t_nsec;
	xfs_diflags_to_iflags(inode, ip);
	xfs_iflags_clear(ip, XFS_IMODIFIED);

	switch (inode->i_mode & S_IFMT) {
	case S_IFREG:
		inode->i_op = &xfs_inode_operations;
		inode->i_fop = &xfs_file_operations;
		inode->i_mapping->a_ops = &xfs_address_space_operations;
		break;
	case S_IFDIR:
		if (xfs_sb_version_hasasciici(&XFS_M(inode->i_sb)->m_sb))
			inode->i_op = &xfs_dir_ci_inode_operations;
		else
			inode->i_op = &xfs_dir_inode_operations;
		inode->i_fop = &xfs_dir_file_operations;
		break;
	case S_IFLNK:
		inode->i_op = &xfs_symlink_inode_operations;
		if (!(ip->i_df.if_flags & XFS_IFINLINE))
			inode->i_mapping->a_ops = &xfs_address_space_operations;
		break;
	default:
		inode->i_op = &xfs_inode_operations;
		init_special_inode(inode, inode->i_mode, inode->i_rdev);
		break;
	}

	xfs_iflags_clear(ip, XFS_INEW);
	barrier();

	unlock_new_inode(inode);
}
+3 −5
Original line number Original line Diff line number Diff line
@@ -18,10 +18,7 @@
#ifndef __XFS_IOPS_H__
#ifndef __XFS_IOPS_H__
#define __XFS_IOPS_H__
#define __XFS_IOPS_H__


extern const struct inode_operations xfs_inode_operations;
struct xfs_inode;
extern const struct inode_operations xfs_dir_inode_operations;
extern const struct inode_operations xfs_dir_ci_inode_operations;
extern const struct inode_operations xfs_symlink_inode_operations;


extern const struct file_operations xfs_file_operations;
extern const struct file_operations xfs_file_operations;
extern const struct file_operations xfs_dir_file_operations;
extern const struct file_operations xfs_dir_file_operations;
@@ -29,8 +26,9 @@ extern const struct file_operations xfs_invis_file_operations;


extern ssize_t xfs_vn_listxattr(struct dentry *, char *data, size_t size);
extern ssize_t xfs_vn_listxattr(struct dentry *, char *data, size_t size);


struct xfs_inode;
extern void xfs_ichgtime(struct xfs_inode *, int);
extern void xfs_ichgtime(struct xfs_inode *, int);
extern void xfs_ichgtime_fast(struct xfs_inode *, struct inode *, int);
extern void xfs_ichgtime_fast(struct xfs_inode *, struct inode *, int);


extern void xfs_setup_inode(struct xfs_inode *);

#endif /* __XFS_IOPS_H__ */
#endif /* __XFS_IOPS_H__ */
+0 −110
Original line number Original line Diff line number Diff line
@@ -581,116 +581,6 @@ xfs_max_file_offset(
	return (((__uint64_t)pagefactor) << bitshift) - 1;
	return (((__uint64_t)pagefactor) << bitshift) - 1;
}
}


STATIC_INLINE void
xfs_set_inodeops(
	struct inode		*inode)
{
	switch (inode->i_mode & S_IFMT) {
	case S_IFREG:
		inode->i_op = &xfs_inode_operations;
		inode->i_fop = &xfs_file_operations;
		inode->i_mapping->a_ops = &xfs_address_space_operations;
		break;
	case S_IFDIR:
		if (xfs_sb_version_hasasciici(&XFS_M(inode->i_sb)->m_sb))
			inode->i_op = &xfs_dir_ci_inode_operations;
		else
			inode->i_op = &xfs_dir_inode_operations;
		inode->i_fop = &xfs_dir_file_operations;
		break;
	case S_IFLNK:
		inode->i_op = &xfs_symlink_inode_operations;
		if (!(XFS_I(inode)->i_df.if_flags & XFS_IFINLINE))
			inode->i_mapping->a_ops = &xfs_address_space_operations;
		break;
	default:
		inode->i_op = &xfs_inode_operations;
		init_special_inode(inode, inode->i_mode, inode->i_rdev);
		break;
	}
}

STATIC_INLINE void
xfs_revalidate_inode(
	xfs_mount_t		*mp,
	struct inode		*inode,
	xfs_inode_t		*ip)
{

	inode->i_mode	= ip->i_d.di_mode;
	inode->i_nlink	= ip->i_d.di_nlink;
	inode->i_uid	= ip->i_d.di_uid;
	inode->i_gid	= ip->i_d.di_gid;

	switch (inode->i_mode & S_IFMT) {
	case S_IFBLK:
	case S_IFCHR:
		inode->i_rdev =
			MKDEV(sysv_major(ip->i_df.if_u2.if_rdev) & 0x1ff,
			      sysv_minor(ip->i_df.if_u2.if_rdev));
		break;
	default:
		inode->i_rdev = 0;
		break;
	}

	inode->i_generation = ip->i_d.di_gen;
	i_size_write(inode, ip->i_d.di_size);
	inode->i_atime.tv_sec	= ip->i_d.di_atime.t_sec;
	inode->i_atime.tv_nsec	= ip->i_d.di_atime.t_nsec;
	inode->i_mtime.tv_sec	= ip->i_d.di_mtime.t_sec;
	inode->i_mtime.tv_nsec	= ip->i_d.di_mtime.t_nsec;
	inode->i_ctime.tv_sec	= ip->i_d.di_ctime.t_sec;
	inode->i_ctime.tv_nsec	= ip->i_d.di_ctime.t_nsec;
	if (ip->i_d.di_flags & XFS_DIFLAG_IMMUTABLE)
		inode->i_flags |= S_IMMUTABLE;
	else
		inode->i_flags &= ~S_IMMUTABLE;
	if (ip->i_d.di_flags & XFS_DIFLAG_APPEND)
		inode->i_flags |= S_APPEND;
	else
		inode->i_flags &= ~S_APPEND;
	if (ip->i_d.di_flags & XFS_DIFLAG_SYNC)
		inode->i_flags |= S_SYNC;
	else
		inode->i_flags &= ~S_SYNC;
	if (ip->i_d.di_flags & XFS_DIFLAG_NOATIME)
		inode->i_flags |= S_NOATIME;
	else
		inode->i_flags &= ~S_NOATIME;
	xfs_iflags_clear(ip, XFS_IMODIFIED);
}

void
xfs_initialize_vnode(
	struct xfs_mount	*mp,
	struct inode		*inode,
	struct xfs_inode	*ip)
{

	if (!ip->i_vnode) {
		ip->i_vnode = inode;
		inode->i_private = ip;
	}

	/*
	 * We need to set the ops vectors, and unlock the inode, but if
	 * we have been called during the new inode create process, it is
	 * too early to fill in the Linux inode.  We will get called a
	 * second time once the inode is properly set up, and then we can
	 * finish our work.
	 */
	if (ip->i_d.di_mode != 0 && (inode->i_state & I_NEW)) {
		xfs_revalidate_inode(mp, inode, ip);
		xfs_set_inodeops(inode);

		xfs_iflags_clear(ip, XFS_INEW);
		barrier();

		unlock_new_inode(inode);
	}
}

int
int
xfs_blkdev_get(
xfs_blkdev_get(
	xfs_mount_t		*mp,
	xfs_mount_t		*mp,
+0 −3
Original line number Original line Diff line number Diff line
@@ -101,9 +101,6 @@ struct block_device;


extern __uint64_t xfs_max_file_offset(unsigned int);
extern __uint64_t xfs_max_file_offset(unsigned int);


extern void xfs_initialize_vnode(struct xfs_mount *mp, struct inode *vp,
		struct xfs_inode *ip);

extern void xfs_flush_inode(struct xfs_inode *);
extern void xfs_flush_inode(struct xfs_inode *);
extern void xfs_flush_device(struct xfs_inode *);
extern void xfs_flush_device(struct xfs_inode *);


+8 −1
Original line number Original line Diff line number Diff line
@@ -287,11 +287,18 @@ finish_inode:
	xfs_iflags_set(ip, XFS_IMODIFIED);
	xfs_iflags_set(ip, XFS_IMODIFIED);
	*ipp = ip;
	*ipp = ip;


	/*
	 * Set up the Linux with the Linux inode.
	 */
	ip->i_vnode = inode;
	inode->i_private = ip;

	/*
	/*
	 * If we have a real type for an on-disk inode, we can set ops(&unlock)
	 * If we have a real type for an on-disk inode, we can set ops(&unlock)
	 * now.	 If it's a new inode being created, xfs_ialloc will handle it.
	 * now.	 If it's a new inode being created, xfs_ialloc will handle it.
	 */
	 */
	xfs_initialize_vnode(mp, inode, ip);
	if (ip->i_d.di_mode != 0)
		xfs_setup_inode(ip);
	return 0;
	return 0;
}
}


Loading