From f4d6b646a1aa6f8e489dd3eeae1a188de0b2a070 Mon Sep 17 00:00:00 2001
From: Samuel Thibault <samuel.thibault@ens-lyon.org>
Date: Tue, 26 Apr 2016 22:37:09 +0200
Subject: Fix supporting >4GiB files in ext2fs

* ext2fs/inode.c (diskfs_user_read_node): When sizeof(off_t) >= 8, add
di->i_size_high as high-64bit part to st->st_size. Drop setting
unused info->i_high_size.
(write_node): When sizeof(off_t) >= 8, write high-64bit part of st->st_size
to di->i_size_high.
* ext2fs/ext2_fs_i.h (ext2_inode_info): Remove i_high_size field.
* pfinet/linux-src/include/linux/ext2_fs_i.h (ext2_inode_info): Likewise.
---
 ext2fs/ext2_fs_i.h |  1 -
 ext2fs/inode.c     | 20 ++++++++++++++------
 2 files changed, 14 insertions(+), 7 deletions(-)

(limited to 'ext2fs')

diff --git a/ext2fs/ext2_fs_i.h b/ext2fs/ext2_fs_i.h
index 72bcd5c0..eefdbfaf 100644
--- a/ext2fs/ext2_fs_i.h
+++ b/ext2fs/ext2_fs_i.h
@@ -35,7 +35,6 @@ struct ext2_inode_info {
 	__u32	i_next_alloc_goal;
 	__u32	i_prealloc_block;
 	__u32	i_prealloc_count;
-	__u32	i_high_size;
 	int	i_new_inode:1;	/* Is a freshly allocated inode */
 };
 
diff --git a/ext2fs/inode.c b/ext2fs/inode.c
index d83bedca..ccc8d699 100644
--- a/ext2fs/inode.c
+++ b/ext2fs/inode.c
@@ -198,13 +198,18 @@ diskfs_user_read_node (struct node *np, struct lookup_context *ctx)
   else
     {
       info->i_dir_acl = 0;
-      info->i_high_size = di->i_size_high;
-      if (info->i_high_size)	/* XXX */
+      if (sizeof (off_t) >= 8)
+	/* 64bit file size */
+	st->st_size += ((off_t) di->i_size_high) << 32;
+      else
 	{
-	  dino_deref (di);
-	  ext2_warning ("cannot handle large file inode %Ld", np->cache_id);
-	  diskfs_end_catch_exception ();
-	  return EFBIG;
+	  if (di->i_size_high)	/* XXX */
+	    {
+	      dino_deref (di);
+	      ext2_warning ("cannot handle large file inode %Ld", np->cache_id);
+	      diskfs_end_catch_exception ();
+	      return EFBIG;
+	    }
 	}
     }
   info->i_block_group = inode_group_num (np->cache_id);
@@ -426,6 +431,9 @@ write_node (struct node *np)
 	{
 	  di->i_dtime = 0;
 	  di->i_size = st->st_size;
+	  if (sizeof (off_t) >= 8 && !S_ISDIR (st->st_mode))
+	    /* 64bit file size */
+	    di->i_size_high = st->st_size >> 32;
 	  di->i_blocks = st->st_blocks;
 	}
 
-- 
cgit v1.2.3