diff options
| author | Ben Hutchings <ben@decadent.org.uk> | 2010-05-17 06:00:00 -0400 |
|---|---|---|
| committer | Theodore Ts'o <tytso@mit.edu> | 2010-05-17 06:00:00 -0400 |
| commit | 4d92dc0f00a775dc2e1267b0e00befb783902fe7 (patch) | |
| tree | 07bb835871dfcc290f5909fe6635ab420ff61420 | |
| parent | 899ad0cea6ad7ff4ba24b16318edbc3cbbe03fad (diff) | |
ext4: Fix compat EXT4_IOC_ADD_GROUP
struct ext4_new_group_input needs to be converted because u64 has
only 32-bit alignment on some 32-bit architectures, notably i386.
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
| -rw-r--r-- | fs/ext4/ext4.h | 16 | ||||
| -rw-r--r-- | fs/ext4/ioctl.c | 25 |
2 files changed, 39 insertions, 2 deletions
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index d8c28f658cb0..2c1165f731ac 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h | |||
| @@ -29,6 +29,9 @@ | |||
| 29 | #include <linux/wait.h> | 29 | #include <linux/wait.h> |
| 30 | #include <linux/blockgroup_lock.h> | 30 | #include <linux/blockgroup_lock.h> |
| 31 | #include <linux/percpu_counter.h> | 31 | #include <linux/percpu_counter.h> |
| 32 | #ifdef __KERNEL__ | ||
| 33 | #include <linux/compat.h> | ||
| 34 | #endif | ||
| 32 | 35 | ||
| 33 | /* | 36 | /* |
| 34 | * The fourth extended filesystem constants/structures | 37 | * The fourth extended filesystem constants/structures |
| @@ -432,6 +435,18 @@ struct ext4_new_group_input { | |||
| 432 | __u16 unused; | 435 | __u16 unused; |
| 433 | }; | 436 | }; |
| 434 | 437 | ||
| 438 | #if defined(__KERNEL__) && defined(CONFIG_COMPAT) | ||
| 439 | struct compat_ext4_new_group_input { | ||
| 440 | u32 group; | ||
| 441 | compat_u64 block_bitmap; | ||
| 442 | compat_u64 inode_bitmap; | ||
| 443 | compat_u64 inode_table; | ||
| 444 | u32 blocks_count; | ||
| 445 | u16 reserved_blocks; | ||
| 446 | u16 unused; | ||
| 447 | }; | ||
| 448 | #endif | ||
| 449 | |||
| 435 | /* The struct ext4_new_group_input in kernel space, with free_blocks_count */ | 450 | /* The struct ext4_new_group_input in kernel space, with free_blocks_count */ |
| 436 | struct ext4_new_group_data { | 451 | struct ext4_new_group_data { |
| 437 | __u32 group; | 452 | __u32 group; |
| @@ -509,6 +524,7 @@ struct ext4_new_group_data { | |||
| 509 | #define EXT4_IOC32_GETRSVSZ _IOR('f', 5, int) | 524 | #define EXT4_IOC32_GETRSVSZ _IOR('f', 5, int) |
| 510 | #define EXT4_IOC32_SETRSVSZ _IOW('f', 6, int) | 525 | #define EXT4_IOC32_SETRSVSZ _IOW('f', 6, int) |
| 511 | #define EXT4_IOC32_GROUP_EXTEND _IOW('f', 7, unsigned int) | 526 | #define EXT4_IOC32_GROUP_EXTEND _IOW('f', 7, unsigned int) |
| 527 | #define EXT4_IOC32_GROUP_ADD _IOW('f', 8, struct compat_ext4_new_group_input) | ||
| 512 | #ifdef CONFIG_JBD2_DEBUG | 528 | #ifdef CONFIG_JBD2_DEBUG |
| 513 | #define EXT4_IOC32_WAIT_FOR_READONLY _IOR('f', 99, int) | 529 | #define EXT4_IOC32_WAIT_FOR_READONLY _IOR('f', 99, int) |
| 514 | #endif | 530 | #endif |
diff --git a/fs/ext4/ioctl.c b/fs/ext4/ioctl.c index 66fa0b030e37..6ddec84846cd 100644 --- a/fs/ext4/ioctl.c +++ b/fs/ext4/ioctl.c | |||
| @@ -373,8 +373,29 @@ long ext4_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
| 373 | case EXT4_IOC32_SETRSVSZ: | 373 | case EXT4_IOC32_SETRSVSZ: |
| 374 | cmd = EXT4_IOC_SETRSVSZ; | 374 | cmd = EXT4_IOC_SETRSVSZ; |
| 375 | break; | 375 | break; |
| 376 | case EXT4_IOC_GROUP_ADD: | 376 | case EXT4_IOC32_GROUP_ADD: { |
| 377 | break; | 377 | struct compat_ext4_new_group_input __user *uinput; |
| 378 | struct ext4_new_group_input input; | ||
| 379 | mm_segment_t old_fs; | ||
| 380 | int err; | ||
| 381 | |||
| 382 | uinput = compat_ptr(arg); | ||
| 383 | err = get_user(input.group, &uinput->group); | ||
| 384 | err |= get_user(input.block_bitmap, &uinput->block_bitmap); | ||
| 385 | err |= get_user(input.inode_bitmap, &uinput->inode_bitmap); | ||
| 386 | err |= get_user(input.inode_table, &uinput->inode_table); | ||
| 387 | err |= get_user(input.blocks_count, &uinput->blocks_count); | ||
| 388 | err |= get_user(input.reserved_blocks, | ||
| 389 | &uinput->reserved_blocks); | ||
| 390 | if (err) | ||
| 391 | return -EFAULT; | ||
| 392 | old_fs = get_fs(); | ||
| 393 | set_fs(KERNEL_DS); | ||
| 394 | err = ext4_ioctl(file, EXT4_IOC_GROUP_ADD, | ||
| 395 | (unsigned long) &input); | ||
| 396 | set_fs(old_fs); | ||
| 397 | return err; | ||
| 398 | } | ||
| 378 | case EXT4_IOC_MOVE_EXT: | 399 | case EXT4_IOC_MOVE_EXT: |
| 379 | break; | 400 | break; |
| 380 | default: | 401 | default: |
