Re: 2G file size limitation question

Albert D. Cahalan (acahalan@cs.uml.edu)
Sat, 10 Jan 1998 06:46:46 -0500 (EST)


>> The i_size field in the inode is the least of our worries.
>> If we need to expand that, we simply put the high 32 bits of
>> size elsewhere --- and there are places where we can put it.
>
> Out of curiosity: Where would you put it?

In a union with i_dir_acl would be a good place,
since I don't expect any 5 GB directories.

>> Nah; if the VFS layer can handle 64-bits, we can make
>> the ext2 structure handle 64-bits.
>
> This sounds like a hen-and-egg problem to me. Until ext2 is really
> known to support larger files (including in the infrastructure,
> e2fstools), there is apparently little motivation to modify the Linux
> kernel for good. OTOH, it seems the ext2 people would not modify the
> file system until the VFS layer can handle it.

Perhaps NFSv3, UFS, and NTFS can save us. The existing ext2 inode
can go a small bit past the 2 GB limit, since i_size is unsigned.

Here is one compatible solution to the problem:

/*
* Structure of an inode on the disk, proposed ext2.
*/
struct ext2_inode {
__u16 i_mode; /* File mode */
__u16 i_uid; /* Owner Uid */
__u32 i_size; /* Size in bytes */
__u32 i_atime; /* Access time */
__u32 i_ctime; /* inode Change time */
__u32 i_mtime; /* Modification time */
__u32 i_dtime; /* Deletion Time */
__u16 i_gid; /* Group Id */
__u16 i_links_count; /* Links count */
__u32 i_blocks; /* Blocks count */
__u32 i_flags; /* File flags */
union {
__u32 i_translator; /* translator (Hurd only) */
__u32 i_res_fork; /* resource fork (Linux privs) */
} u1;
__u32 i_block[EXT2_N_BLOCKS];/* Pointers to blocks */
__u32 i_version; /* File version (for NFS) */
__u32 i_file_acl; /* File ACL */
union {
__u32 i_dir_acl; /* Directory ACL */
__u32 i_size_high; /* high 32 bits of 64-bit size */
} u2;
__u32 i_reserved1;
__u16 i_reserved2;
__u16 i_mode_high; /* extra mode bits (Hurd only) */
__u16 i_uid_high; /* high 16 bits of 32-bit UID */
__u16 i_gid_high; /* high 16 bits of 32-bit GID */
__u32 i_author; /* author (Hurd only) */
};

/*
* In case people like incompatible change...
* This is cleaner but maybe not worth the trouble.
*/
struct ext3_inode {
__u16 i_mode; /* File mode */
__u16 i_version; /* File version (for NFS) */
__u32 i_flags; /* File flags */
__u32 i_gid; /* Group Id */
__u32 i_uid; /* Owner Uid */
__u32 i_atime; /* Access time (damn POSIX) */
__u32 i_mtime; /* Modification time */
__u32 i_ctime; /* inode Change time */
__u32 i_reserved;
__u16 i_checksum; /* inode checksum */
/* here to end can be a 94-byte symlink */
__u16 i_links_count; /* Links count */
__u32 i_size; /* low 32 bits of 64-bit size */
__u32 i_file_acl; /* File ACL */
__u32 i_res_fork; /* resource fork (Linux privs) */
/* here to end can be 20 direct blocks */
__u32 i_block[18]; /* Pointers to blocks */
union {
__u32 i_size_high; /* top bits of size, only need 5 to 12 */
__u32 i_dir_acl; /* Directory ACL */
} u;
__u32 i_blocks; /* Blocks count */
};