Patchwork [07/31] libext2fs: When writing a file that has a i_size > 2GB, set the large_file feature flag and update the superblock.

login
register
mail settings
Submitter Darrick J. Wong
Date Oct. 1, 2013, 1:27 a.m.
Message ID <20131001012728.28415.89082.stgit@birch.djwong.org>
Download mbox | patch
Permalink /patch/279286/
State Accepted
Headers show

Comments

Darrick J. Wong - Oct. 1, 2013, 1:27 a.m.
If someone tries to write a file that is larger than 2GB, we need to set the
large_file feature flag to affirm that i_size_hi can hold meaningful contents.
(I don't see anything checking large_file except e2fsck...)

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 lib/ext2fs/fileio.c |   12 ++++++++++++
 1 file changed, 12 insertions(+)



--
To unsubscribe from this list: send the line "unsubscribe linux-ext4" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Theodore Ts'o - Oct. 7, 2013, 1:14 p.m.
On Mon, Sep 30, 2013 at 06:27:28PM -0700, Darrick J. Wong wrote:
> If someone tries to write a file that is larger than 2GB, we need to set the
> large_file feature flag to affirm that i_size_hi can hold meaningful contents.
> (I don't see anything checking large_file except e2fsck...)

The large_file feature is there to protect ancient (2.2?) kernels that
didn't understand large files.  It's largely not needed in modern
kernels, which all understand it.

Still this patch is good for correctness; thanks for pointing it out!
Thanks, applied.

						- Ted
--
To unsubscribe from this list: send the line "unsubscribe linux-ext4" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Patch

diff --git a/lib/ext2fs/fileio.c b/lib/ext2fs/fileio.c
index 1f7002c..ae5cbf1 100644
--- a/lib/ext2fs/fileio.c
+++ b/lib/ext2fs/fileio.c
@@ -389,6 +389,18 @@  errcode_t ext2fs_file_set_size2(ext2_file_t file, ext2_off64_t size)
 	old_truncate = ((old_size + file->fs->blocksize - 1) >>
 		      EXT2_BLOCK_SIZE_BITS(file->fs->super)) + 1;
 
+	/* If we're writing a large file, set the large_file flag */
+	if (LINUX_S_ISREG(file->inode.i_mode) &&
+	    EXT2_I_SIZE(&file->inode) > 0x7FFFFFFULL &&
+	    (!EXT2_HAS_RO_COMPAT_FEATURE(file->fs->super,
+					 EXT2_FEATURE_RO_COMPAT_LARGE_FILE) ||
+	     file->fs->super->s_rev_level == EXT2_GOOD_OLD_REV)) {
+		file->fs->super->s_feature_ro_compat |=
+				EXT2_FEATURE_RO_COMPAT_LARGE_FILE;
+		ext2fs_update_dynamic_rev(file->fs);
+		ext2fs_mark_super_dirty(file->fs);
+	}
+
 	file->inode.i_size = size & 0xffffffff;
 	file->inode.i_size_high = (size >> 32);
 	if (file->ino) {