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 /fs | |
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>
Diffstat (limited to 'fs')
-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: |