Skip to content

Commit

Permalink
[XFS] avoid xfs_getattr in XFS_IOC_FSGETXATTR ioctl
Browse files Browse the repository at this point in the history
No need to call into xfs_getattr and put a big bhv_vattr_t on the stack
just to get a little information from the XFS inode.

Add a helper called xfs_ioc_fsgetxattr instead that deals with retrieving
the information in a clean way.

SGI-PV: 968563
SGI-Modid: xfs-linux-melb:xfs-kern:29780a

Signed-off-by: Christoph Hellwig <hch@infradead.org>
Signed-off-by: Lachlan McIlroy <lachlan@sgi.com>
Signed-off-by: Tim Shimmin <tes@sgi.com>
  • Loading branch information
Christoph Hellwig authored and Tim Shimmin committed Oct 16, 2007
1 parent 859d718 commit c83bfab
Showing 1 changed file with 46 additions and 44 deletions.
90 changes: 46 additions & 44 deletions fs/xfs/linux-2.6/xfs_ioctl.c
Original file line number Diff line number Diff line change
Expand Up @@ -708,6 +708,12 @@ xfs_ioc_xattr(
unsigned int cmd,
void __user *arg);

STATIC int
xfs_ioc_fsgetxattr(
xfs_inode_t *ip,
int attr,
void __user *arg);

STATIC int
xfs_ioc_getbmap(
struct xfs_inode *ip,
Expand Down Expand Up @@ -783,11 +789,13 @@ xfs_ioctl(
case XFS_IOC_GETVERSION:
return put_user(inode->i_generation, (int __user *)arg);

case XFS_IOC_FSGETXATTR:
return xfs_ioc_fsgetxattr(ip, 0, arg);
case XFS_IOC_FSGETXATTRA:
return xfs_ioc_fsgetxattr(ip, 1, arg);
case XFS_IOC_GETXFLAGS:
case XFS_IOC_SETXFLAGS:
case XFS_IOC_FSGETXATTR:
case XFS_IOC_FSSETXATTR:
case XFS_IOC_FSGETXATTRA:
return xfs_ioc_xattr(vp, ip, filp, cmd, arg);

case XFS_IOC_FSSETDM: {
Expand Down Expand Up @@ -1161,6 +1169,42 @@ xfs_di2lxflags(
return flags;
}

STATIC int
xfs_ioc_fsgetxattr(
xfs_inode_t *ip,
int attr,
void __user *arg)
{
struct fsxattr fa;

xfs_ilock(ip, XFS_ILOCK_SHARED);
fa.fsx_xflags = xfs_ip2xflags(ip);
fa.fsx_extsize = ip->i_d.di_extsize << ip->i_mount->m_sb.sb_blocklog;
fa.fsx_projid = ip->i_d.di_projid;

if (attr) {
if (ip->i_afp) {
if (ip->i_afp->if_flags & XFS_IFEXTENTS)
fa.fsx_nextents = ip->i_afp->if_bytes /
sizeof(xfs_bmbt_rec_t);
else
fa.fsx_nextents = ip->i_d.di_anextents;
} else
fa.fsx_nextents = 0;
} else {
if (ip->i_df.if_flags & XFS_IFEXTENTS)
fa.fsx_nextents = ip->i_df.if_bytes /
sizeof(xfs_bmbt_rec_t);
else
fa.fsx_nextents = ip->i_d.di_nextents;
}
xfs_iunlock(ip, XFS_ILOCK_SHARED);

if (copy_to_user(arg, &fa, sizeof(fa)))
return -EFAULT;
return 0;
}

STATIC int
xfs_ioc_xattr(
bhv_vnode_t *vp,
Expand All @@ -1180,27 +1224,6 @@ xfs_ioc_xattr(
return -ENOMEM;

switch (cmd) {
case XFS_IOC_FSGETXATTR: {
vattr->va_mask = XFS_AT_XFLAGS | XFS_AT_EXTSIZE | \
XFS_AT_NEXTENTS | XFS_AT_PROJID;
error = xfs_getattr(ip, vattr, 0);
if (unlikely(error)) {
error = -error;
break;
}

fa.fsx_xflags = vattr->va_xflags;
fa.fsx_extsize = vattr->va_extsize;
fa.fsx_nextents = vattr->va_nextents;
fa.fsx_projid = vattr->va_projid;

if (copy_to_user(arg, &fa, sizeof(fa))) {
error = -EFAULT;
break;
}
break;
}

case XFS_IOC_FSSETXATTR: {
if (copy_from_user(&fa, arg, sizeof(fa))) {
error = -EFAULT;
Expand All @@ -1223,27 +1246,6 @@ xfs_ioc_xattr(
break;
}

case XFS_IOC_FSGETXATTRA: {
vattr->va_mask = XFS_AT_XFLAGS | XFS_AT_EXTSIZE | \
XFS_AT_ANEXTENTS | XFS_AT_PROJID;
error = xfs_getattr(ip, vattr, 0);
if (unlikely(error)) {
error = -error;
break;
}

fa.fsx_xflags = vattr->va_xflags;
fa.fsx_extsize = vattr->va_extsize;
fa.fsx_nextents = vattr->va_anextents;
fa.fsx_projid = vattr->va_projid;

if (copy_to_user(arg, &fa, sizeof(fa))) {
error = -EFAULT;
break;
}
break;
}

case XFS_IOC_GETXFLAGS: {
flags = xfs_di2lxflags(ip->i_d.di_flags);
if (copy_to_user(arg, &flags, sizeof(flags)))
Expand Down

0 comments on commit c83bfab

Please sign in to comment.