From c512d30ab2dcbf8922086795e897798a446c7566 Mon Sep 17 00:00:00 2001 From: tjr Date: Wed, 18 Feb 2004 14:08:25 +0000 Subject: Add partial support for large (>4GB) files on ext2 filesystems. This support is partial in that it will refuse to create large files on filesystems that haven't been upgraded to EXT2_DYN_REV or that don't have the EXT2_FEATURE_RO_COMPAT_LARGE_FILE flag set in the superblock. MFC after: 2 weeks --- sys/gnu/ext2fs/ext2_fs.h | 3 ++- sys/gnu/ext2fs/ext2_inode.c | 10 ++++++++++ sys/gnu/ext2fs/ext2_inode_cnv.c | 4 ++++ sys/gnu/fs/ext2fs/ext2_fs.h | 3 ++- sys/gnu/fs/ext2fs/ext2_inode.c | 10 ++++++++++ sys/gnu/fs/ext2fs/ext2_inode_cnv.c | 4 ++++ 6 files changed, 32 insertions(+), 2 deletions(-) (limited to 'sys/gnu') diff --git a/sys/gnu/ext2fs/ext2_fs.h b/sys/gnu/ext2fs/ext2_fs.h index 2943593..4c9466d 100644 --- a/sys/gnu/ext2fs/ext2_fs.h +++ b/sys/gnu/ext2fs/ext2_fs.h @@ -486,7 +486,8 @@ struct ext2_super_block { EXT2_FEATURE_RO_COMPAT_LARGE_FILE| \ EXT2_FEATURE_RO_COMPAT_BTREE_DIR) #else -#define EXT2_FEATURE_RO_COMPAT_SUPP EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER +#define EXT2_FEATURE_RO_COMPAT_SUPP (EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER| \ + EXT2_FEATURE_RO_COMPAT_LARGE_FILE) #endif /* diff --git a/sys/gnu/ext2fs/ext2_inode.c b/sys/gnu/ext2fs/ext2_inode.c index ec7215e..d940a5c 100644 --- a/sys/gnu/ext2fs/ext2_inode.c +++ b/sys/gnu/ext2fs/ext2_inode.c @@ -164,6 +164,16 @@ printf("ext2_truncate called %d to %d\n", VTOI(ovp)->i_number, length); * value of oszie is 0, length will be at least 1. */ if (osize < length) { + /* + * XXX Refuse to extend files past 2GB on old format + * filesystems or ones that don't already have the + * large file flag set in the superblock. + */ + if (osize < 0x8000000 && length >= 0x80000000 && + (oip->i_e2fs->s_es->s_rev_level == EXT2_GOOD_OLD_REV || + (oip->i_e2fs->s_es->s_feature_ro_compat & + EXT2_FEATURE_RO_COMPAT_LARGE_FILE) == 0)) + return (EFBIG); offset = blkoff(fs, length - 1); lbn = lblkno(fs, length - 1); aflags = B_CLRBUF; diff --git a/sys/gnu/ext2fs/ext2_inode_cnv.c b/sys/gnu/ext2fs/ext2_inode_cnv.c index d64e549..12b5f4a 100644 --- a/sys/gnu/ext2fs/ext2_inode_cnv.c +++ b/sys/gnu/ext2fs/ext2_inode_cnv.c @@ -77,6 +77,8 @@ ext2_ei2i(ei, ip) */ ip->i_mode = ei->i_links_count ? ei->i_mode : 0; ip->i_size = ei->i_size; + if (S_ISREG(ip->i_mode)) + ip->i_size |= ((u_int64_t)ei->i_size_high) << 32; ip->i_atime = ei->i_atime; ip->i_mtime = ei->i_mtime; ip->i_ctime = ei->i_ctime; @@ -112,6 +114,8 @@ ext2_i2ei(ip, ei) */ ei->i_dtime = ei->i_links_count ? 0 : ip->i_mtime; ei->i_size = ip->i_size; + if (S_ISREG(ip->i_mode)) + ei->i_size_high = ip->i_size >> 32; ei->i_atime = ip->i_atime; ei->i_mtime = ip->i_mtime; ei->i_ctime = ip->i_ctime; diff --git a/sys/gnu/fs/ext2fs/ext2_fs.h b/sys/gnu/fs/ext2fs/ext2_fs.h index 2943593..4c9466d 100644 --- a/sys/gnu/fs/ext2fs/ext2_fs.h +++ b/sys/gnu/fs/ext2fs/ext2_fs.h @@ -486,7 +486,8 @@ struct ext2_super_block { EXT2_FEATURE_RO_COMPAT_LARGE_FILE| \ EXT2_FEATURE_RO_COMPAT_BTREE_DIR) #else -#define EXT2_FEATURE_RO_COMPAT_SUPP EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER +#define EXT2_FEATURE_RO_COMPAT_SUPP (EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER| \ + EXT2_FEATURE_RO_COMPAT_LARGE_FILE) #endif /* diff --git a/sys/gnu/fs/ext2fs/ext2_inode.c b/sys/gnu/fs/ext2fs/ext2_inode.c index ec7215e..d940a5c 100644 --- a/sys/gnu/fs/ext2fs/ext2_inode.c +++ b/sys/gnu/fs/ext2fs/ext2_inode.c @@ -164,6 +164,16 @@ printf("ext2_truncate called %d to %d\n", VTOI(ovp)->i_number, length); * value of oszie is 0, length will be at least 1. */ if (osize < length) { + /* + * XXX Refuse to extend files past 2GB on old format + * filesystems or ones that don't already have the + * large file flag set in the superblock. + */ + if (osize < 0x8000000 && length >= 0x80000000 && + (oip->i_e2fs->s_es->s_rev_level == EXT2_GOOD_OLD_REV || + (oip->i_e2fs->s_es->s_feature_ro_compat & + EXT2_FEATURE_RO_COMPAT_LARGE_FILE) == 0)) + return (EFBIG); offset = blkoff(fs, length - 1); lbn = lblkno(fs, length - 1); aflags = B_CLRBUF; diff --git a/sys/gnu/fs/ext2fs/ext2_inode_cnv.c b/sys/gnu/fs/ext2fs/ext2_inode_cnv.c index d64e549..12b5f4a 100644 --- a/sys/gnu/fs/ext2fs/ext2_inode_cnv.c +++ b/sys/gnu/fs/ext2fs/ext2_inode_cnv.c @@ -77,6 +77,8 @@ ext2_ei2i(ei, ip) */ ip->i_mode = ei->i_links_count ? ei->i_mode : 0; ip->i_size = ei->i_size; + if (S_ISREG(ip->i_mode)) + ip->i_size |= ((u_int64_t)ei->i_size_high) << 32; ip->i_atime = ei->i_atime; ip->i_mtime = ei->i_mtime; ip->i_ctime = ei->i_ctime; @@ -112,6 +114,8 @@ ext2_i2ei(ip, ei) */ ei->i_dtime = ei->i_links_count ? 0 : ip->i_mtime; ei->i_size = ip->i_size; + if (S_ISREG(ip->i_mode)) + ei->i_size_high = ip->i_size >> 32; ei->i_atime = ip->i_atime; ei->i_mtime = ip->i_mtime; ei->i_ctime = ip->i_ctime; -- cgit v1.1