aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext4
diff options
context:
space:
mode:
authorTheodore Ts'o <tytso@mit.edu>2014-03-20 00:32:57 -0400
committerTheodore Ts'o <tytso@mit.edu>2014-03-20 00:32:57 -0400
commitc4f65706056e9f0c2cf126b29c6920a179d91150 (patch)
tree7e9c20d13d06f6b6bedffff60cf61a093a625bac /fs/ext4
parent9c191f701ce9f9bc604e88a5dc69cd943daa5d3b (diff)
ext4: kill i_version support for Hurd-castrated file systems
The Hurd file system uses uses the inode field which is now used for i_version for its translator block. This means that ext2 file systems that are formatted for GNU Hurd can't be used to support NFSv4. Given that Hurd file systems don't support extents, and a huge number of modern file system features, this is no great loss. If we don't do this, the attempt to update the i_version field will stomp over the translator block field, which will cause file system corruption for Hurd file systems. This can be replicated via: mke2fs -t ext2 -o hurd /dev/vdc mount -t ext4 /dev/vdc /vdc touch /vdc/bug0000 umount /dev/vdc e2fsck -f /dev/vdc Addresses-Debian-Bug: #738758 Reported-By: Gabriele Giacone <1o5g4r8o@gmail.com> Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
Diffstat (limited to 'fs/ext4')
-rw-r--r--fs/ext4/inode.c29
1 files changed, 18 insertions, 11 deletions
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index 7cc24555eca8..ed2c13a7f293 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -4168,11 +4168,14 @@ struct inode *ext4_iget(struct super_block *sb, unsigned long ino)
4168 EXT4_INODE_GET_XTIME(i_atime, inode, raw_inode); 4168 EXT4_INODE_GET_XTIME(i_atime, inode, raw_inode);
4169 EXT4_EINODE_GET_XTIME(i_crtime, ei, raw_inode); 4169 EXT4_EINODE_GET_XTIME(i_crtime, ei, raw_inode);
4170 4170
4171 inode->i_version = le32_to_cpu(raw_inode->i_disk_version); 4171 if (EXT4_SB(inode->i_sb)->s_es->s_creator_os !=
4172 if (EXT4_INODE_SIZE(inode->i_sb) > EXT4_GOOD_OLD_INODE_SIZE) { 4172 cpu_to_le32(EXT4_OS_HURD)) {
4173 if (EXT4_FITS_IN_INODE(raw_inode, ei, i_version_hi)) 4173 inode->i_version = le32_to_cpu(raw_inode->i_disk_version);
4174 inode->i_version |= 4174 if (EXT4_INODE_SIZE(inode->i_sb) > EXT4_GOOD_OLD_INODE_SIZE) {
4175 (__u64)(le32_to_cpu(raw_inode->i_version_hi)) << 32; 4175 if (EXT4_FITS_IN_INODE(raw_inode, ei, i_version_hi))
4176 inode->i_version |=
4177 (__u64)(le32_to_cpu(raw_inode->i_version_hi)) << 32;
4178 }
4176 } 4179 }
4177 4180
4178 ret = 0; 4181 ret = 0;
@@ -4388,12 +4391,16 @@ static int ext4_do_update_inode(handle_t *handle,
4388 raw_inode->i_block[block] = ei->i_data[block]; 4391 raw_inode->i_block[block] = ei->i_data[block];
4389 } 4392 }
4390 4393
4391 raw_inode->i_disk_version = cpu_to_le32(inode->i_version); 4394 if (EXT4_SB(inode->i_sb)->s_es->s_creator_os !=
4392 if (ei->i_extra_isize) { 4395 cpu_to_le32(EXT4_OS_HURD)) {
4393 if (EXT4_FITS_IN_INODE(raw_inode, ei, i_version_hi)) 4396 raw_inode->i_disk_version = cpu_to_le32(inode->i_version);
4394 raw_inode->i_version_hi = 4397 if (ei->i_extra_isize) {
4395 cpu_to_le32(inode->i_version >> 32); 4398 if (EXT4_FITS_IN_INODE(raw_inode, ei, i_version_hi))
4396 raw_inode->i_extra_isize = cpu_to_le16(ei->i_extra_isize); 4399 raw_inode->i_version_hi =
4400 cpu_to_le32(inode->i_version >> 32);
4401 raw_inode->i_extra_isize =
4402 cpu_to_le16(ei->i_extra_isize);
4403 }
4397 } 4404 }
4398 4405
4399 ext4_inode_csum_set(inode, raw_inode, ei); 4406 ext4_inode_csum_set(inode, raw_inode, ei);