Summary of this patch:
[19/21] enlarge max file size and max filesystem size
- With "-O large_block" option in mke2fs, the maximum size of
a file is (blocksize) * (2^32-1) bytes, and of a filesystem
is (pagesize) * (2^32-1).
Signed-off-by: Takashi Sato [email protected]
---
diff -Nurp old/ext2resize-1.1.19/src/ext2.c ext2resize-1.1.19/src/ext2.c
--- old/ext2resize-1.1.19/src/ext2.c 2006-03-20 21:46:08.000000000 +0800
+++ ext2resize-1.1.19/src/ext2.c 2006-03-20 21:47:33.000000000 +0800
@@ -295,7 +295,6 @@ int ext2_block_iterate(struct ext2_fs *f
blk_t curblock;
int count = 0;
int i;
- int i512perblock = 1 << (fs->logsize - 9);
unsigned long long apb;
apb = fs->u32perblock;
@@ -341,7 +340,7 @@ int ext2_block_iterate(struct ext2_fs *f
inode->i_block[EXT2_DIND_BLOCK] = dindblk;
bh = ext2_bread(fs, inode->i_block[EXT2_DIND_BLOCK]);
memset(bh->data, 0, fs->blocksize);
- inode->i_blocks += i512perblock;
+ inode->i_blocks += I_BLOCKS;
}
else
bh = ext2_bread(fs, inode->i_block[EXT2_DIND_BLOCK]);
@@ -363,7 +362,7 @@ int ext2_block_iterate(struct ext2_fs *f
ext2_zero_blocks(fs, block, 1);
ext2_set_block_state(fs, block, 1, 1);
bh->dirty = 1;
- inode->i_blocks += i512perblock;
+ inode->i_blocks += I_BLOCKS;
inode->i_mtime = time(NULL);
ext2_brelse(bh, 0);
return 1;
@@ -379,7 +378,7 @@ int ext2_block_iterate(struct ext2_fs *f
bh2 = ext2_bread(fs, udata[i]);
udata2 = (__u32 *)bh2->data;
- count += i512perblock;
+ count += I_BLOCKS;
for (j = 0; j < fs->u32perblock; j++, curblock++) {
if (action == EXT2_ACTION_ADD && !udata2[j]) {
@@ -390,7 +389,7 @@ int ext2_block_iterate(struct ext2_fs *f
curblock, udata[i]);
bh2->dirty = 1;
udata2[j] = block;
- inode->i_blocks += i512perblock;
+ inode->i_blocks += I_BLOCKS;
if (new_size > inode->i_size)
inode->i_size = new_size;
inode->i_mtime = time(NULL);
@@ -407,7 +406,7 @@ int ext2_block_iterate(struct ext2_fs *f
curblock, udata[i]);
bh2->dirty = 1;
udata2[j] = 0;
- inode->i_blocks -= i512perblock;
+ inode->i_blocks -= I_BLOCKS;
inode->i_mtime = time(NULL);
if (!(fs->flags & FL_ONLINE))
ext2_set_block_state(fs, block,
@@ -418,7 +417,7 @@ int ext2_block_iterate(struct ext2_fs *f
return curblock;
}
if (udata2[j]) {
- count += i512perblock;
+ count += I_BLOCKS;
if (count >= inode->i_blocks &&
action != EXT2_ACTION_ADD)
return -1;
@@ -787,7 +786,7 @@ static blk_t ext2_get_reserved(struct ex
for (i = 0; i < fs->numgroups; i++)
sb_groups += ext2_bg_has_super(fs, i);
- resgdblocks = ((inode->i_blocks >> (fs->logsize - 9)) -
+ resgdblocks = ((inode->i_blocks >> I_BLOCKS_SHIFT) -
(inode->i_block[EXT2_IND_BLOCK] ? 1 : 0) -
(inode->i_block[EXT2_DIND_BLOCK] ? 1 : 0)) /
sb_groups;
@@ -820,15 +819,16 @@ static blk_t ext2_get_reserved(struct ex
EXT2_FEATURE_COMPAT_RESIZE_INODE)
#define EXT2_OPEN_RO_COMPAT_UNSUPP ~(EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER | \
EXT2_FEATURE_RO_COMPAT_LARGE_FILE)
-#define EXT2_OPEN_INCOMPAT_UNSUPP ~EXT2_FEATURE_INCOMPAT_FILETYPE
+#define EXT2_OPEN_INCOMPAT_UNSUPP ~(EXT2_FEATURE_INCOMPAT_FILETYPE | \
+ EXT2_FEATURE_INCOMPAT_LARGE_BLOCK)
-struct ext2_fs *ext2_open(struct ext2_dev_handle *handle, blk_t newblocks,
+struct ext2_fs *ext2_open(struct ext2_dev_handle *handle, blk64_t newblocks,
int flags)
{
struct ext2_fs *fs;
struct ext2_inode inode;
int maxgroups;
- blk_t devsize;
+ blk64_t devsize;
blk_t residue;
if (flags & FL_DEBUG)
@@ -909,6 +909,12 @@ struct ext2_fs *ext2_open(struct ext2_de
newblocks = devsize;
else if (fs->flags & FL_KB_BLOCKS)
newblocks >>= fs->logsize - 10;
+ if (newblocks > ~0U) {
+ /* actually we can't process fs over 4G-1 amount of blocks */
+ fprintf(stderr, "%s: can't resize filesystem over %uTB\n",
+ fs->prog, fs->blocksize >> (40 - 32));
+ goto error_free_bcache;
+ }
if (fs->flags & FL_VERBOSE)
printf("new filesystem size %d\n", newblocks);
@@ -926,13 +932,13 @@ struct ext2_fs *ext2_open(struct ext2_de
if (devsize < newblocks && !(fs->flags & FL_PREPARE)) {
char *junk[fs->blocksize];
- fprintf(stderr, "%s: warning - device size %u, specified %u\n",
+ fprintf(stderr, "%s: warning - device size %llu, specified %llu\n",
fs->prog, devsize, newblocks);
ext2_read_blocks(fs, junk, newblocks - 1, 1);
} else if (fs->sb.s_blocks_count > devsize) {
char *junk[fs->blocksize];
- fprintf(stderr, "%s: warning - device size %u, filesystem %u\n",
+ fprintf(stderr, "%s: warning - device size %llu, filesystem %u\n",
fs->prog, devsize, fs->sb.s_blocks_count);
ext2_read_blocks(fs, junk, fs->sb.s_blocks_count - 1, 1);
@@ -1014,7 +1020,7 @@ void ext2_fix_resize_inode(struct ext2_f
if (inode->i_block[EXT2_DIND_BLOCK]) {
ext2_zero_blocks(fs, inode->i_block[EXT2_DIND_BLOCK], 1);
- inode->i_blocks = 1 << (fs->logsize - 9);
+ inode->i_blocks = I_BLOCKS;
}
for (i = 0, block = fs->sb.s_first_data_block + fs->newgdblocks + 1;
diff -Nurp old/ext2resize-1.1.19/src/ext2_fs.h ext2resize-1.1.19/src/ext2_fs.h
--- old/ext2resize-1.1.19/src/ext2_fs.h 2002-07-04 01:52:24.000000000 +0800
+++ ext2resize-1.1.19/src/ext2_fs.h 2006-03-20 21:47:33.000000000 +0800
@@ -509,6 +509,8 @@ struct ext2_super_block {
#define EXT2_FEATURE_INCOMPAT_FILETYPE 0x0002
#define EXT3_FEATURE_INCOMPAT_RECOVER 0x0004 /* Needs recovery */
#define EXT3_FEATURE_INCOMPAT_JOURNAL_DEV 0x0008 /* Journal device */
+/* EXT3_FEATURE_INCOMPAT_EXTENTS 0x0040 */
+#define EXT2_FEATURE_INCOMPAT_LARGE_BLOCK 0x0080
#define EXT2_FEATURE_COMPAT_SUPP 0
#define EXT2_FEATURE_INCOMPAT_SUPP EXT2_FEATURE_INCOMPAT_FILETYPE
diff -Nurp old/ext2resize-1.1.19/src/ext2.h ext2resize-1.1.19/src/ext2.h
--- old/ext2resize-1.1.19/src/ext2.h 2006-03-20 21:47:15.000000000 +0800
+++ ext2resize-1.1.19/src/ext2.h 2006-03-20 21:47:33.000000000 +0800
@@ -51,6 +51,7 @@ static const char _ext2_h[] = "$Id: ext2
#define cpu_to_le32(a) (a)
#endif
typedef u_int32_t blk_t;
+typedef unsigned long long blk64_t; /* don't use autoheader for now */
#include "ext2_fs.h"
@@ -85,7 +86,7 @@ struct ext2_buffer_head
struct ext2_dev_ops
{
void (*close)(void *cookie);
- blk_t (*get_size)(void *cookie);
+ blk64_t (*get_size)(void *cookie);
void (*read)(void *cookie, void *ptr, blk_t block, blk_t num);
void (*set_blocksize)(void *cookie, int logsize);
void (*sync)(void *cookie);
@@ -176,7 +177,7 @@ int ext2_bg_has_super(struct ext2_fs *fs
unsigned int ext2_list_backups(struct ext2_fs *fs, unsigned int *three,
unsigned int *five, unsigned int *seven);
void ext2_move_blocks(struct ext2_fs *fs, blk_t src, blk_t num, blk_t dest);
-struct ext2_fs *ext2_open(struct ext2_dev_handle *handle, blk_t newblocks,
+struct ext2_fs *ext2_open(struct ext2_dev_handle *handle, blk64_t newblocks,
int kb_blocks);
void ext2_read_blocks(struct ext2_fs *fs, void *ptr, blk_t block,
blk_t numblocks);
@@ -248,6 +249,11 @@ void ext2_fix_resize_inode(struct ext2_f
#define clear_bit(buf, offset) buf[(offset)>>3] &= ~_bitmap[(offset)&7]
#define check_bit(buf, offset) (buf[(offset)>>3] & _bitmap[(offset)&7])
+/* Switch macro for EXT2_FEATURE_INCOMPAT_LARGE_BLOCK */
+#define I_BLOCKS_SHIFT (EXT2_HAS_INCOMPAT_FEATURE(&fs->sb, \
+ EXT2_FEATURE_INCOMPAT_LARGE_BLOCK) ? 0 : (fs->logsize - 9))
+#define I_BLOCKS (1 << I_BLOCKS_SHIFT)
+
#ifdef USE_EXT2_IS_DATA_BLOCK
static int __inline__ ext2_is_data_block(struct ext2_fs *fs, blk_t block)
{
diff -Nurp old/ext2resize-1.1.19/src/ext2online.c ext2resize-1.1.19/src/ext2online.c
--- old/ext2resize-1.1.19/src/ext2online.c 2006-03-20 21:46:08.000000000 +0800
+++ ext2resize-1.1.19/src/ext2online.c 2006-03-20 21:47:33.000000000 +0800
@@ -573,7 +573,8 @@ int main(int argc, char *argv[])
char *progname;
struct ext2_dev_handle *handle;
struct ext2_fs *fs;
- blk_t resize = 0, realsize = 0;
+ blk64_t resize = 0;
+ blk_t realsize = 0;
char mod = '\0';
int flags = FL_SAFE;
@@ -603,7 +604,7 @@ int main(int argc, char *argv[])
/* See if the user has specified a filesystem size */
if (argc == 2) {
- sscanf(argv[1], "%i%c", &resize, &mod);
+ sscanf(argv[1], "%lli%c", &resize, &mod);
switch (mod) { /* Order of these options is important!! */
case 't':
diff -Nurp old/ext2resize-1.1.19/src/ext2prepare.c ext2resize-1.1.19/src/ext2prepare.c
--- old/ext2resize-1.1.19/src/ext2prepare.c 2006-03-20 21:46:08.000000000 +0800
+++ ext2resize-1.1.19/src/ext2prepare.c 2006-03-20 21:47:33.000000000 +0800
@@ -228,7 +228,7 @@ int main(int argc, char *argv[])
char *dev;
char *progname;
blk_t maxres;
- blk_t resize = 0;
+ blk64_t resize = 0;
char mod = '\0';
int flags = FL_SAFE;
@@ -248,7 +248,7 @@ int main(int argc, char *argv[])
if (handle == NULL)
return 1;
- sscanf(argv[1], "%i%c", &resize, &mod);
+ sscanf(argv[1], "%lli%c", &resize, &mod);
switch (mod) { /* Order of these options is important!! */
case 't':
@@ -282,11 +282,13 @@ int main(int argc, char *argv[])
"%s: won't prepare 1k block filesystem over 128GB.\n"
"\tToo much space would be wasted.\n", progname);
return 1;
- } else if ((fs->blocksize == 4096 && fs->newblocks > 1<<30) ||
+ } else if (!EXT2_HAS_INCOMPAT_FEATURE(&fs->sb, EXT2_FEATURE_INCOMPAT_LARGE_BLOCK)) {
+ if ((fs->blocksize == 4096 && fs->newblocks > 1<<29) ||
fs->newblocks > 1<<31) {
fprintf(stderr,
"%s: can't resize filesystem over 2TB.\n", progname);
return 1;
+ }
}
maxres = (1 + fs->u32perblock) * fs->u32perblock + EXT2_NDIR_BLOCKS;
diff -Nurp old/ext2resize-1.1.19/src/ext2resize.c ext2resize-1.1.19/src/ext2resize.c
--- old/ext2resize-1.1.19/src/ext2resize.c 2001-04-19 06:31:21.000000000 +0800
+++ ext2resize-1.1.19/src/ext2resize.c 2006-03-20 21:47:33.000000000 +0800
@@ -30,7 +30,7 @@ static const char _ext2resize_c[] = "$Id
void usage(FILE *outfile, char *progname)
{
fprintf(outfile,
- "usage: %s [-dfquvV] device [new_size[bkmgt]]\n\t"
+ "usage: %s [-dfquvV] device [new_size[bkmgt]]\n"
"\t-d, --debug : turn debug info on\n"
"\t-f, --force : skip safety checks\n"
"\t-q, --quiet : be quiet (print only errors)\n"
@@ -81,7 +81,7 @@ int main(int argc, char *argv[])
char *dev;
char *progname;
char mod = '\0';
- blk_t resize = 0;
+ blk64_t resize = 0;
int flags = FL_SAFE;
progname = strrchr(argv[0], '/') ? strrchr(argv[0], '/') + 1 : argv[0];
@@ -102,7 +102,7 @@ int main(int argc, char *argv[])
return 1;
if (argc == 2) {
- sscanf(argv[1], "%i%c", &resize, &mod);
+ sscanf(argv[1], "%lli%c", &resize, &mod);
switch (mod) { /* Order of these options is important!! */
case 't':
diff -Nurp old/ext2resize-1.1.19/src/ext2_unix_io.c ext2resize-1.1.19/src/ext2_unix_io.c
--- old/ext2resize-1.1.19/src/ext2_unix_io.c 2004-09-30 22:04:04.000000000 +0800
+++ ext2resize-1.1.19/src/ext2_unix_io.c 2006-03-20 21:47:33.000000000 +0800
@@ -96,7 +96,7 @@ static int valid_offset(int fd, __loff_t
return 1;
}
-static blk_t do_get_size(void *cookie)
+static blk64_t do_get_size(void *cookie)
{
struct my_cookie *monster = cookie;
blk_t size;
@@ -138,7 +138,7 @@ static blk_t do_get_size(void *cookie)
/* Reset filesystem position? */
ext2_llseek(monster->fdread, monster->readoff, SEEK_SET);
- size = high >> 9;
+ return high >> monster->logsize;
}
return size >> (monster->logsize - 9);
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[Index of Archives]
[Kernel Newbies]
[Netfilter]
[Bugtraq]
[Photo]
[Stuff]
[Gimp]
[Yosemite News]
[MIPS Linux]
[ARM Linux]
[Linux Security]
[Linux RAID]
[Video 4 Linux]
[Linux for the blind]
[Linux Resources]