aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext4/inode.c
diff options
context:
space:
mode:
authorAneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>2008-01-28 23:58:26 -0500
committerTheodore Ts'o <tytso@mit.edu>2008-01-28 23:58:26 -0500
commit0fc1b451471dfc3cabd6e99ef441df9804616e63 (patch)
treeb018b6ddc5bb5f02b985b06c11f0c01adb38167a /fs/ext4/inode.c
parenta48380f769dfed6163fb82a68b13bd562ea1e027 (diff)
ext4: Add support for 48 bit inode i_blocks.
Use the __le16 l_i_reserved1 field of the linux2 struct of ext4_inode to represet the higher 16 bits for i_blocks. With this change max_file size becomes (2**48 -1 )* 512 bytes. We add a RO_COMPAT feature to the super block to indicate that inode have i_blocks represented as a split 48 bits. Super block with this feature set cannot be mounted read write on a kernel with CONFIG_LSF disabled. Super block flag EXT4_FEATURE_RO_COMPAT_HUGE_FILE Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
Diffstat (limited to 'fs/ext4/inode.c')
-rw-r--r--fs/ext4/inode.c58
1 files changed, 56 insertions, 2 deletions
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index e6634550cfc8..bb89fe727bb1 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -2667,6 +2667,22 @@ void ext4_get_inode_flags(struct ext4_inode_info *ei)
2667 if (flags & S_DIRSYNC) 2667 if (flags & S_DIRSYNC)
2668 ei->i_flags |= EXT4_DIRSYNC_FL; 2668 ei->i_flags |= EXT4_DIRSYNC_FL;
2669} 2669}
2670static blkcnt_t ext4_inode_blocks(struct ext4_inode *raw_inode,
2671 struct ext4_inode_info *ei)
2672{
2673 blkcnt_t i_blocks ;
2674 struct super_block *sb = ei->vfs_inode.i_sb;
2675
2676 if (EXT4_HAS_RO_COMPAT_FEATURE(sb,
2677 EXT4_FEATURE_RO_COMPAT_HUGE_FILE)) {
2678 /* we are using combined 48 bit field */
2679 i_blocks = ((u64)le16_to_cpu(raw_inode->i_blocks_high)) << 32 |
2680 le32_to_cpu(raw_inode->i_blocks_lo);
2681 return i_blocks;
2682 } else {
2683 return le32_to_cpu(raw_inode->i_blocks_lo);
2684 }
2685}
2670 2686
2671void ext4_read_inode(struct inode * inode) 2687void ext4_read_inode(struct inode * inode)
2672{ 2688{
@@ -2715,8 +2731,8 @@ void ext4_read_inode(struct inode * inode)
2715 * recovery code: that's fine, we're about to complete 2731 * recovery code: that's fine, we're about to complete
2716 * the process of deleting those. */ 2732 * the process of deleting those. */
2717 } 2733 }
2718 inode->i_blocks = le32_to_cpu(raw_inode->i_blocks);
2719 ei->i_flags = le32_to_cpu(raw_inode->i_flags); 2734 ei->i_flags = le32_to_cpu(raw_inode->i_flags);
2735 inode->i_blocks = ext4_inode_blocks(raw_inode, ei);
2720 ei->i_file_acl = le32_to_cpu(raw_inode->i_file_acl_lo); 2736 ei->i_file_acl = le32_to_cpu(raw_inode->i_file_acl_lo);
2721 if (EXT4_SB(inode->i_sb)->s_es->s_creator_os != 2737 if (EXT4_SB(inode->i_sb)->s_es->s_creator_os !=
2722 cpu_to_le32(EXT4_OS_HURD)) { 2738 cpu_to_le32(EXT4_OS_HURD)) {
@@ -2799,6 +2815,43 @@ bad_inode:
2799 return; 2815 return;
2800} 2816}
2801 2817
2818static int ext4_inode_blocks_set(handle_t *handle,
2819 struct ext4_inode *raw_inode,
2820 struct ext4_inode_info *ei)
2821{
2822 struct inode *inode = &(ei->vfs_inode);
2823 u64 i_blocks = inode->i_blocks;
2824 struct super_block *sb = inode->i_sb;
2825 int err = 0;
2826
2827 if (i_blocks <= ~0U) {
2828 /*
2829 * i_blocks can be represnted in a 32 bit variable
2830 * as multiple of 512 bytes
2831 */
2832 raw_inode->i_blocks_lo = cpu_to_le32((u32)i_blocks);
2833 raw_inode->i_blocks_high = 0;
2834 } else if (i_blocks <= 0xffffffffffffULL) {
2835 /*
2836 * i_blocks can be represented in a 48 bit variable
2837 * as multiple of 512 bytes
2838 */
2839 err = ext4_update_rocompat_feature(handle, sb,
2840 EXT4_FEATURE_RO_COMPAT_HUGE_FILE);
2841 if (err)
2842 goto err_out;
2843 /* i_block is stored in the split 48 bit fields */
2844 raw_inode->i_blocks_lo = cpu_to_le32((u32)i_blocks);
2845 raw_inode->i_blocks_high = cpu_to_le16(i_blocks >> 32);
2846 } else {
2847 ext4_error(sb, __FUNCTION__,
2848 "Wrong inode i_blocks count %llu\n",
2849 (unsigned long long)inode->i_blocks);
2850 }
2851err_out:
2852 return err;
2853}
2854
2802/* 2855/*
2803 * Post the struct inode info into an on-disk inode location in the 2856 * Post the struct inode info into an on-disk inode location in the
2804 * buffer-cache. This gobbles the caller's reference to the 2857 * buffer-cache. This gobbles the caller's reference to the
@@ -2853,7 +2906,8 @@ static int ext4_do_update_inode(handle_t *handle,
2853 EXT4_INODE_SET_XTIME(i_atime, inode, raw_inode); 2906 EXT4_INODE_SET_XTIME(i_atime, inode, raw_inode);
2854 EXT4_EINODE_SET_XTIME(i_crtime, ei, raw_inode); 2907 EXT4_EINODE_SET_XTIME(i_crtime, ei, raw_inode);
2855 2908
2856 raw_inode->i_blocks = cpu_to_le32(inode->i_blocks); 2909 if (ext4_inode_blocks_set(handle, raw_inode, ei))
2910 goto out_brelse;
2857 raw_inode->i_dtime = cpu_to_le32(ei->i_dtime); 2911 raw_inode->i_dtime = cpu_to_le32(ei->i_dtime);
2858 raw_inode->i_flags = cpu_to_le32(ei->i_flags); 2912 raw_inode->i_flags = cpu_to_le32(ei->i_flags);
2859 if (EXT4_SB(inode->i_sb)->s_es->s_creator_os != 2913 if (EXT4_SB(inode->i_sb)->s_es->s_creator_os !=