aboutsummaryrefslogtreecommitdiff
path: root/sys/gnu
diff options
context:
space:
mode:
authorTim J. Robbins <tjr@FreeBSD.org>2004-02-18 14:08:25 +0000
committerTim J. Robbins <tjr@FreeBSD.org>2004-02-18 14:08:25 +0000
commitba122e68e0326bfc958c7a7622d02ce1247cd75b (patch)
tree5838560abb54c61b72c76ee0ffcb6112ee73874d /sys/gnu
parent26d2edc770da50d4982eea7daba5cf28a8c711f8 (diff)
downloadsrc-ba122e68e0326bfc958c7a7622d02ce1247cd75b.tar.gz
src-ba122e68e0326bfc958c7a7622d02ce1247cd75b.zip
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
Notes
Notes: svn path=/head/; revision=125962
Diffstat (limited to 'sys/gnu')
-rw-r--r--sys/gnu/ext2fs/ext2_fs.h3
-rw-r--r--sys/gnu/ext2fs/ext2_inode.c10
-rw-r--r--sys/gnu/ext2fs/ext2_inode_cnv.c4
-rw-r--r--sys/gnu/fs/ext2fs/ext2_fs.h3
-rw-r--r--sys/gnu/fs/ext2fs/ext2_inode.c10
-rw-r--r--sys/gnu/fs/ext2fs/ext2_inode_cnv.c4
6 files changed, 32 insertions, 2 deletions
diff --git a/sys/gnu/ext2fs/ext2_fs.h b/sys/gnu/ext2fs/ext2_fs.h
index 29435937181b..4c9466db64b3 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 ec7215e37f51..d940a5c69a15 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 d64e5498776b..12b5f4a66cbe 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 29435937181b..4c9466db64b3 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 ec7215e37f51..d940a5c69a15 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 d64e5498776b..12b5f4a66cbe 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;