Whamcloud - gitweb
b=24214 Discard preallocation blocks after failed allocated.
[fs/lustre-release.git] / ldiskfs / kernel_patches / patches / ext3-fiemap-2.6-rhel5.patch
1 diff -rupN linux-2.6.18-164.6.1_1/fs/ext3/ioctl.c linux-2.6.18-164.6.1_2/fs/ext3/ioctl.c
2 --- linux-2.6.18-164.6.1_1/fs/ext3/ioctl.c      2009-12-22 12:37:55.000000000 +0530
3 +++ linux-2.6.18-164.6.1_2/fs/ext3/ioctl.c      2009-12-22 12:40:44.000000000 +0530
4 @@ -16,6 +16,70 @@
5  #include <asm/uaccess.h>
6  #include <linux/namei.h>
7  
8 +/* So that the fiemap access checks can't overflow on 32 bit machines. */
9 +#define FIEMAP_MAX_EXTENTS     (UINT_MAX / sizeof(struct fiemap_extent))
10 +
11 +static int fiemap_check_ranges(struct super_block *sb,
12 +                              u64 start, u64 len, u64 *new_len)
13 +{
14 +       *new_len = len;
15 +
16 +       if (len == 0)
17 +               return -EINVAL;
18 +
19 +       if (start > sb->s_maxbytes)
20 +               return -EFBIG;
21 +
22 +       /*
23 +        * Shrink request scope to what the fs can actually handle.
24 +        */
25 +       if ((len > sb->s_maxbytes) ||
26 +           (sb->s_maxbytes - len) < start)
27 +               *new_len = sb->s_maxbytes - start;
28 +
29 +       return 0;
30 +}
31 +
32 +int ioctl_fiemap(struct inode *inode, struct file *filp, unsigned long arg)
33 +{
34 +       struct fiemap fiemap;
35 +       u64 len;
36 +       struct fiemap_extent_info fieinfo = {0, };
37 +       struct super_block *sb = inode->i_sb;
38 +       int error = 0;
39 +
40 +       if (copy_from_user(&fiemap, (struct fiemap __user *) arg,
41 +                          sizeof(struct fiemap)))
42 +                return -EFAULT;
43 +
44 +       if (fiemap.fm_extent_count > FIEMAP_MAX_EXTENTS)
45 +               return -EINVAL;
46 +
47 +       error = fiemap_check_ranges(sb, fiemap.fm_start, fiemap.fm_length,
48 +                                   &len);
49 +       if (error)
50 +               return error;
51 +
52 +       fieinfo.fi_flags = fiemap.fm_flags;
53 +       fieinfo.fi_extents_max = fiemap.fm_extent_count;
54 +       fieinfo.fi_extents_start = (struct fiemap_extent *)(arg + sizeof(fiemap));
55 +
56 +       if (fiemap.fm_extent_count != 0 &&
57 +           !access_ok(VERIFY_WRITE, (void *)arg,
58 +                      offsetof(typeof(fiemap), fm_extents[fiemap.fm_extent_count])))
59 +               return -EFAULT;
60 +
61 +       if (fieinfo.fi_flags & FIEMAP_FLAG_SYNC)
62 +               filemap_write_and_wait(inode->i_mapping);
63 +
64 +       error = ext3_fiemap(inode, &fieinfo, fiemap.fm_start, len);
65 +       fiemap.fm_flags = fieinfo.fi_flags;
66 +       fiemap.fm_mapped_extents = fieinfo.fi_extents_mapped;
67 +       if (copy_to_user((char *)arg, &fiemap, sizeof(fiemap)))
68 +               error = -EFAULT;
69 +
70 +       return error;
71 +}
72  
73  int ext3_ioctl (struct inode * inode, struct file * filp, unsigned int cmd,
74                 unsigned long arg)
75 @@ -276,7 +340,9 @@ flags_err:
76  
77                 return err;
78         }
79 -
80 +       case EXT3_IOC_FIEMAP: {
81 +               return ioctl_fiemap(inode, filp, arg);
82 +       }
83  
84         default:
85                 return -ENOTTY;
86 diff -rupN linux-2.6.18-164.6.1_1/include/linux/ext3_fs.h linux-2.6.18-164.6.1_2/include/linux/ext3_fs.h
87 --- linux-2.6.18-164.6.1_1/include/linux/ext3_fs.h      2009-12-22 12:37:55.000000000 +0530
88 +++ linux-2.6.18-164.6.1_2/include/linux/ext3_fs.h      2009-12-22 12:43:02.000000000 +0530
89 @@ -260,6 +260,7 @@ struct ext3_new_group_data {
90  #define        EXT3_IOC_SETVERSION             _IOW('f', 4, long)
91  #define EXT3_IOC_GROUP_EXTEND          _IOW('f', 7, unsigned long)
92  #define EXT3_IOC_GROUP_ADD             _IOW('f', 8,struct ext3_new_group_input)
93 +#define EXT3_IOC_FIEMAP                _IOWR('f', 11, struct fiemap)
94  #define        EXT3_IOC_GETVERSION_OLD         _IOR('v', 1, long)
95  #define        EXT3_IOC_SETVERSION_OLD         _IOW('v', 2, long)
96  #ifdef CONFIG_JBD_DEBUG