diff options
Diffstat (limited to 'fs/xfs/linux-2.6/xfs_ioctl.c')
-rw-r--r-- | fs/xfs/linux-2.6/xfs_ioctl.c | 35 |
1 files changed, 30 insertions, 5 deletions
diff --git a/fs/xfs/linux-2.6/xfs_ioctl.c b/fs/xfs/linux-2.6/xfs_ioctl.c index b06ede1d0bed..acca2c5ca3fa 100644 --- a/fs/xfs/linux-2.6/xfs_ioctl.c +++ b/fs/xfs/linux-2.6/xfs_ioctl.c | |||
@@ -624,6 +624,10 @@ xfs_ioc_space( | |||
624 | 624 | ||
625 | if (filp->f_flags & (O_NDELAY|O_NONBLOCK)) | 625 | if (filp->f_flags & (O_NDELAY|O_NONBLOCK)) |
626 | attr_flags |= XFS_ATTR_NONBLOCK; | 626 | attr_flags |= XFS_ATTR_NONBLOCK; |
627 | |||
628 | if (filp->f_flags & O_DSYNC) | ||
629 | attr_flags |= XFS_ATTR_SYNC; | ||
630 | |||
627 | if (ioflags & IO_INVIS) | 631 | if (ioflags & IO_INVIS) |
628 | attr_flags |= XFS_ATTR_DMI; | 632 | attr_flags |= XFS_ATTR_DMI; |
629 | 633 | ||
@@ -695,14 +699,19 @@ xfs_ioc_fsgeometry_v1( | |||
695 | xfs_mount_t *mp, | 699 | xfs_mount_t *mp, |
696 | void __user *arg) | 700 | void __user *arg) |
697 | { | 701 | { |
698 | xfs_fsop_geom_v1_t fsgeo; | 702 | xfs_fsop_geom_t fsgeo; |
699 | int error; | 703 | int error; |
700 | 704 | ||
701 | error = xfs_fs_geometry(mp, (xfs_fsop_geom_t *)&fsgeo, 3); | 705 | error = xfs_fs_geometry(mp, &fsgeo, 3); |
702 | if (error) | 706 | if (error) |
703 | return -error; | 707 | return -error; |
704 | 708 | ||
705 | if (copy_to_user(arg, &fsgeo, sizeof(fsgeo))) | 709 | /* |
710 | * Caller should have passed an argument of type | ||
711 | * xfs_fsop_geom_v1_t. This is a proper subset of the | ||
712 | * xfs_fsop_geom_t that xfs_fs_geometry() fills in. | ||
713 | */ | ||
714 | if (copy_to_user(arg, &fsgeo, sizeof(xfs_fsop_geom_v1_t))) | ||
706 | return -XFS_ERROR(EFAULT); | 715 | return -XFS_ERROR(EFAULT); |
707 | return 0; | 716 | return 0; |
708 | } | 717 | } |
@@ -985,10 +994,22 @@ xfs_ioctl_setattr( | |||
985 | 994 | ||
986 | /* | 995 | /* |
987 | * Extent size must be a multiple of the appropriate block | 996 | * Extent size must be a multiple of the appropriate block |
988 | * size, if set at all. | 997 | * size, if set at all. It must also be smaller than the |
998 | * maximum extent size supported by the filesystem. | ||
999 | * | ||
1000 | * Also, for non-realtime files, limit the extent size hint to | ||
1001 | * half the size of the AGs in the filesystem so alignment | ||
1002 | * doesn't result in extents larger than an AG. | ||
989 | */ | 1003 | */ |
990 | if (fa->fsx_extsize != 0) { | 1004 | if (fa->fsx_extsize != 0) { |
991 | xfs_extlen_t size; | 1005 | xfs_extlen_t size; |
1006 | xfs_fsblock_t extsize_fsb; | ||
1007 | |||
1008 | extsize_fsb = XFS_B_TO_FSB(mp, fa->fsx_extsize); | ||
1009 | if (extsize_fsb > MAXEXTLEN) { | ||
1010 | code = XFS_ERROR(EINVAL); | ||
1011 | goto error_return; | ||
1012 | } | ||
992 | 1013 | ||
993 | if (XFS_IS_REALTIME_INODE(ip) || | 1014 | if (XFS_IS_REALTIME_INODE(ip) || |
994 | ((mask & FSX_XFLAGS) && | 1015 | ((mask & FSX_XFLAGS) && |
@@ -997,6 +1018,10 @@ xfs_ioctl_setattr( | |||
997 | mp->m_sb.sb_blocklog; | 1018 | mp->m_sb.sb_blocklog; |
998 | } else { | 1019 | } else { |
999 | size = mp->m_sb.sb_blocksize; | 1020 | size = mp->m_sb.sb_blocksize; |
1021 | if (extsize_fsb > mp->m_sb.sb_agblocks / 2) { | ||
1022 | code = XFS_ERROR(EINVAL); | ||
1023 | goto error_return; | ||
1024 | } | ||
1000 | } | 1025 | } |
1001 | 1026 | ||
1002 | if (fa->fsx_extsize % size) { | 1027 | if (fa->fsx_extsize % size) { |