More patch description fixups. Standardize case.
[ext4-patch-queue.git] / large-file.patch
blob761817e380229626a8cc84684b28360e0d0b0d48
1 ext4: Support large files
3 From: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
5 This patch converts ext4_inode i_blocks to represent total
6 blocks occupied by the inode in file system block size.
7 Earlier the variable used to represent this in 512 byte
8 block size. This actually limited the total size of the file.
10 The feature is enabled transparently when we write an inode
11 whose i_blocks cannot be represnted as 512 byte units in a
12 48 bit variable.
14 inode flag EXT4_HUGE_FILE_FL
16 Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
17 ---
19 fs/ext4/inode.c | 32 +++++++++++++++++++++++++-------
20 fs/ext4/super.c | 9 ++++++---
21 include/linux/ext4_fs.h | 3 ++-
22 3 files changed, 33 insertions(+), 11 deletions(-)
25 diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
26 index bb89fe7..9cf8572 100644
27 --- a/fs/ext4/inode.c
28 +++ b/fs/ext4/inode.c
29 @@ -2671,14 +2671,20 @@ static blkcnt_t ext4_inode_blocks(struct ext4_inode *raw_inode,
30 struct ext4_inode_info *ei)
32 blkcnt_t i_blocks ;
33 - struct super_block *sb = ei->vfs_inode.i_sb;
34 + struct inode *inode = &(ei->vfs_inode);
35 + struct super_block *sb = inode->i_sb;
37 if (EXT4_HAS_RO_COMPAT_FEATURE(sb,
38 EXT4_FEATURE_RO_COMPAT_HUGE_FILE)) {
39 /* we are using combined 48 bit field */
40 i_blocks = ((u64)le16_to_cpu(raw_inode->i_blocks_high)) << 32 |
41 le32_to_cpu(raw_inode->i_blocks_lo);
42 - return i_blocks;
43 + if (ei->i_flags & EXT4_HUGE_FILE_FL) {
44 + /* i_blocks represent file system block size */
45 + return i_blocks << (inode->i_blkbits - 9);
46 + } else {
47 + return i_blocks;
48 + }
49 } else {
50 return le32_to_cpu(raw_inode->i_blocks_lo);
52 @@ -2829,8 +2835,9 @@ static int ext4_inode_blocks_set(handle_t *handle,
53 * i_blocks can be represnted in a 32 bit variable
54 * as multiple of 512 bytes
56 - raw_inode->i_blocks_lo = cpu_to_le32((u32)i_blocks);
57 + raw_inode->i_blocks_lo = cpu_to_le32(i_blocks);
58 raw_inode->i_blocks_high = 0;
59 + ei->i_flags &= ~EXT4_HUGE_FILE_FL;
60 } else if (i_blocks <= 0xffffffffffffULL) {
62 * i_blocks can be represented in a 48 bit variable
63 @@ -2841,12 +2848,23 @@ static int ext4_inode_blocks_set(handle_t *handle,
64 if (err)
65 goto err_out;
66 /* i_block is stored in the split 48 bit fields */
67 - raw_inode->i_blocks_lo = cpu_to_le32((u32)i_blocks);
68 + raw_inode->i_blocks_lo = cpu_to_le32(i_blocks);
69 raw_inode->i_blocks_high = cpu_to_le16(i_blocks >> 32);
70 + ei->i_flags &= ~EXT4_HUGE_FILE_FL;
71 } else {
72 - ext4_error(sb, __FUNCTION__,
73 - "Wrong inode i_blocks count %llu\n",
74 - (unsigned long long)inode->i_blocks);
75 + /*
76 + * i_blocks should be represented in a 48 bit variable
77 + * as multiple of file system block size
78 + */
79 + err = ext4_update_rocompat_feature(handle, sb,
80 + EXT4_FEATURE_RO_COMPAT_HUGE_FILE);
81 + if (err)
82 + goto err_out;
83 + ei->i_flags |= EXT4_HUGE_FILE_FL;
84 + /* i_block is stored in file system block size */
85 + i_blocks = i_blocks >> (inode->i_blkbits - 9);
86 + raw_inode->i_blocks_lo = cpu_to_le32(i_blocks);
87 + raw_inode->i_blocks_high = cpu_to_le16(i_blocks >> 32);
89 err_out:
90 return err;
91 diff --git a/fs/ext4/super.c b/fs/ext4/super.c
92 index 2b9dc96..64067de 100644
93 --- a/fs/ext4/super.c
94 +++ b/fs/ext4/super.c
95 @@ -1631,11 +1631,14 @@ static loff_t ext4_max_size(int bits)
96 upper_limit >>= (bits - 9);
98 } else {
99 - /* We use 48 bit ext4_inode i_blocks */
100 + /*
101 + * We use 48 bit ext4_inode i_blocks
102 + * With EXT4_HUGE_FILE_FL set the i_blocks
103 + * represent total number of blocks in
104 + * file system block size
105 + */
106 upper_limit = (1LL << 48) - 1;
108 - /* total blocks in file system block size */
109 - upper_limit >>= (bits - 9);
112 /* indirect blocks */
113 diff --git a/include/linux/ext4_fs.h b/include/linux/ext4_fs.h
114 index be25eca..6ae91f4 100644
115 --- a/include/linux/ext4_fs.h
116 +++ b/include/linux/ext4_fs.h
117 @@ -178,8 +178,9 @@ struct ext4_group_desc
118 #define EXT4_NOTAIL_FL 0x00008000 /* file tail should not be merged */
119 #define EXT4_DIRSYNC_FL 0x00010000 /* dirsync behaviour (directories only) */
120 #define EXT4_TOPDIR_FL 0x00020000 /* Top of directory hierarchies*/
121 -#define EXT4_RESERVED_FL 0x80000000 /* reserved for ext4 lib */
122 +#define EXT4_HUGE_FILE_FL 0x00040000 /* Set to each huge file */
123 #define EXT4_EXTENTS_FL 0x00080000 /* Inode uses extents */
124 +#define EXT4_RESERVED_FL 0x80000000 /* reserved for ext4 lib */
126 #define EXT4_FL_USER_VISIBLE 0x000BDFFF /* User visible flags */
127 #define EXT4_FL_USER_MODIFIABLE 0x000380FF /* User modifiable flags */