1 diff -rupN linux-2.6.18-164.6.1_1/fs/ext4/ext4.h linux-2.6.18-164.6.1_2/fs/ext4/ext4.h
2 --- linux-2.6.18-164.6.1_1/fs/ext4/ext4.h 2009-12-22 13:07:27.000000000 +0530
3 +++ linux-2.6.18-164.6.1_2/fs/ext4/ext4.h 2009-12-22 13:10:18.000000000 +0530
4 @@ -305,6 +305,7 @@ struct ext4_new_group_data {
5 #define EXT4_IOC_GROUP_EXTEND _IOW('f', 7, unsigned long)
6 #define EXT4_IOC_GROUP_ADD _IOW('f', 8, struct ext4_new_group_input)
7 #define EXT4_IOC_MIGRATE _IO('f', 9)
8 +#define EXT4_IOC_FIEMAP _IOWR('f', 11, struct fiemap)
9 /* note ioctl 11 reserved for filesystem-independent FIEMAP ioctl */
12 diff -rupN linux-2.6.18-164.6.1_1/fs/ext4/ioctl.c linux-2.6.18-164.6.1_2/fs/ext4/ioctl.c
13 --- linux-2.6.18-164.6.1_1/fs/ext4/ioctl.c 2009-12-22 13:06:51.000000000 +0530
14 +++ linux-2.6.18-164.6.1_2/fs/ext4/ioctl.c 2009-12-22 13:09:45.000000000 +0530
16 #include "ext4_jbd2.h"
19 +/* So that the fiemap access checks can't overflow on 32 bit machines. */
20 +#define FIEMAP_MAX_EXTENTS (UINT_MAX / sizeof(struct fiemap_extent))
22 +static int fiemap_check_ranges(struct super_block *sb,
23 + u64 start, u64 len, u64 *new_len)
30 + if (start > sb->s_maxbytes)
34 + * Shrink request scope to what the fs can actually handle.
36 + if ((len > sb->s_maxbytes) ||
37 + (sb->s_maxbytes - len) < start)
38 + *new_len = sb->s_maxbytes - start;
43 +int ioctl_fiemap(struct inode *inode, struct file *filp, unsigned long arg)
45 + struct fiemap fiemap;
47 + struct fiemap_extent_info fieinfo = {0, };
48 + struct super_block *sb = inode->i_sb;
51 + if (copy_from_user(&fiemap, (struct fiemap __user *) arg,
52 + sizeof(struct fiemap)))
55 + if (fiemap.fm_extent_count > FIEMAP_MAX_EXTENTS)
58 + error = fiemap_check_ranges(sb, fiemap.fm_start, fiemap.fm_length,
63 + fieinfo.fi_flags = fiemap.fm_flags;
64 + fieinfo.fi_extents_max = fiemap.fm_extent_count;
65 + fieinfo.fi_extents_start = (struct fiemap_extent *)(arg + sizeof(fiemap));
67 + if (fiemap.fm_extent_count != 0 &&
68 + !access_ok(VERIFY_WRITE, (void *)arg,
69 + offsetof(typeof(fiemap), fm_extents[fiemap.fm_extent_count])))
72 + if (fieinfo.fi_flags & FIEMAP_FLAG_SYNC)
73 + filemap_write_and_wait(inode->i_mapping);
75 + error = ext4_fiemap(inode, &fieinfo, fiemap.fm_start, len);
76 + fiemap.fm_flags = fieinfo.fi_flags;
77 + fiemap.fm_mapped_extents = fieinfo.fi_extents_mapped;
78 + if (copy_to_user((char *)arg, &fiemap, sizeof(fiemap)))
84 long ext4_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
86 struct inode *inode = filp->f_dentry->d_inode;
87 @@ -249,6 +314,9 @@ flags_out:
88 mutex_unlock(&(inode->i_mutex));
91 + case EXT4_IOC_FIEMAP: {
92 + return ioctl_fiemap(inode, filp, arg);