[RFC][19/21]ext2resize enlarge file size and filesystem size

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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]
  Powered by Linux