linux-fsdevel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 3/9] support >32 bit ext4 filesystem block type in kernel
@ 2006-08-10  1:21 Mingming Cao
  2006-08-10  6:40 ` Andrew Morton
  0 siblings, 1 reply; 3+ messages in thread
From: Mingming Cao @ 2006-08-10  1:21 UTC (permalink / raw)
  To: akpm; +Cc: linux-fsdevel, ext2-devel, linux-kernel


Redefine ext4 in-kernel filesystem block type (ext4_fsblk_t) from unsigned
long to sector_t, to allow kernel to handle  >32 bit ext4 blocks.

Signed-Off-By: Mingming Cao <cmm@us.ibm.com>


---

 linux-2.6.18-rc4-ming/fs/ext4/balloc.c          |   22 +++++++-------------
 linux-2.6.18-rc4-ming/fs/ext4/ialloc.c          |   11 ++++++----
 linux-2.6.18-rc4-ming/fs/ext4/resize.c          |   13 +++++-------
 linux-2.6.18-rc4-ming/fs/ext4/super.c           |    8 +++----
 linux-2.6.18-rc4-ming/include/linux/ext4_fs.h   |   26 ++++++++++++++++++++++++
 linux-2.6.18-rc4-ming/include/linux/ext4_fs_i.h |    4 +--
 6 files changed, 53 insertions(+), 31 deletions(-)

diff -puN fs/ext4/balloc.c~ext4_fsblk_sector_t fs/ext4/balloc.c
--- linux-2.6.18-rc4/fs/ext4/balloc.c~ext4_fsblk_sector_t	2006-08-09 15:41:51.530285904 -0700
+++ linux-2.6.18-rc4-ming/fs/ext4/balloc.c	2006-08-09 15:41:51.553286090 -0700
@@ -37,7 +37,6 @@
 

 #define in_range(b, first, len)	((b) >= (first) && (b) <= (first) + (len) - 1)
-
 struct ext4_group_desc * ext4_get_group_desc(struct super_block * sb,
 					     unsigned int block_group,
 					     struct buffer_head ** bh)
@@ -339,10 +338,7 @@ void ext4_free_blocks_sb(handle_t *handl
 
 do_more:
 	overflow = 0;
-	block_group = (block - le32_to_cpu(es->s_first_data_block)) /
-		      EXT4_BLOCKS_PER_GROUP(sb);
-	bit = (block - le32_to_cpu(es->s_first_data_block)) %
-		      EXT4_BLOCKS_PER_GROUP(sb);
+	ext4_get_group_no_and_offset(sb, block, &block_group, &bit);
 	/*
 	 * Check to see if we are freeing blocks across a group
 	 * boundary.
@@ -1204,7 +1200,7 @@ ext4_fsblk_t ext4_new_blocks(handle_t *h
 {
 	struct buffer_head *bitmap_bh = NULL;
 	struct buffer_head *gdp_bh;
-	int group_no;
+	unsigned long group_no;
 	int goal_group;
 	ext4_grpblk_t grp_target_blk;	/* blockgroup relative goal block */
 	ext4_grpblk_t grp_alloc_blk;	/* blockgroup-relative allocated block*/
@@ -1267,8 +1263,7 @@ ext4_fsblk_t ext4_new_blocks(handle_t *h
 	if (goal < le32_to_cpu(es->s_first_data_block) ||
 	    goal >= le32_to_cpu(es->s_blocks_count))
 		goal = le32_to_cpu(es->s_first_data_block);
-	group_no = (goal - le32_to_cpu(es->s_first_data_block)) /
-			EXT4_BLOCKS_PER_GROUP(sb);
+	ext4_get_group_no_and_offset(sb, goal, &group_no, &grp_target_blk);
 	gdp = ext4_get_group_desc(sb, group_no, &gdp_bh);
 	if (!gdp)
 		goto io_error;
@@ -1285,8 +1280,6 @@ retry:
 		my_rsv = NULL;
 
 	if (free_blocks > 0) {
-		grp_target_blk = ((goal - le32_to_cpu(es->s_first_data_block)) %
-				EXT4_BLOCKS_PER_GROUP(sb));
 		bitmap_bh = read_block_bitmap(sb, group_no);
 		if (!bitmap_bh)
 			goto io_error;
@@ -1413,7 +1406,7 @@ allocated:
 	if (ret_block + num - 1 >= le32_to_cpu(es->s_blocks_count)) {
 		ext4_error(sb, "ext4_new_block",
 			    "block("E3FSBLK") >= blocks count(%d) - "
-			    "block_group = %d, es == %p ", ret_block,
+			    "block_group = %lu, es == %p ", ret_block,
 			le32_to_cpu(es->s_blocks_count), group_no, es);
 		goto out;
 	}
@@ -1527,9 +1520,10 @@ ext4_fsblk_t ext4_count_free_blocks(stru
 static inline int
 block_in_use(ext4_fsblk_t block, struct super_block *sb, unsigned char *map)
 {
-	return ext4_test_bit ((block -
-		le32_to_cpu(EXT4_SB(sb)->s_es->s_first_data_block)) %
-			 EXT4_BLOCKS_PER_GROUP(sb), map);
+	ext4_grpblk_t offset;
+
+	ext4_get_group_no_and_offset(sb, block, NULL, &offset);
+	return ext4_test_bit (offset, map);
 }
 
 static inline int test_root(int a, int b)
diff -puN fs/ext4/ialloc.c~ext4_fsblk_sector_t fs/ext4/ialloc.c
--- linux-2.6.18-rc4/fs/ext4/ialloc.c~ext4_fsblk_sector_t	2006-08-09 15:41:51.533285928 -0700
+++ linux-2.6.18-rc4-ming/fs/ext4/ialloc.c	2006-08-09 15:41:51.554286098 -0700
@@ -23,7 +23,7 @@
 #include <linux/buffer_head.h>
 #include <linux/random.h>
 #include <linux/bitops.h>
-
+#include <linux/blkdev.h>
 #include <asm/byteorder.h>
 
 #include "xattr.h"
@@ -274,7 +274,8 @@ static int find_group_orlov(struct super
 	freei = percpu_counter_read_positive(&sbi->s_freeinodes_counter);
 	avefreei = freei / ngroups;
 	freeb = percpu_counter_read_positive(&sbi->s_freeblocks_counter);
-	avefreeb = freeb / ngroups;
+	avefreeb = freeb;
+	sector_div(avefreeb, ngroups);
 	ndirs = percpu_counter_read_positive(&sbi->s_dirs_counter);
 
 	if ((parent == sb->s_root->d_inode) ||
@@ -303,13 +304,15 @@ static int find_group_orlov(struct super
 		goto fallback;
 	}
 
-	blocks_per_dir = (le32_to_cpu(es->s_blocks_count) - freeb) / ndirs;
+	blocks_per_dir = le32_to_cpu(es->s_blocks_count) - freeb;
+	sector_div(blocks_per_dir, ndirs);
 
 	max_dirs = ndirs / ngroups + inodes_per_group / 16;
 	min_inodes = avefreei - inodes_per_group / 4;
 	min_blocks = avefreeb - EXT4_BLOCKS_PER_GROUP(sb) / 4;
 
-	max_debt = EXT4_BLOCKS_PER_GROUP(sb) / max(blocks_per_dir, (ext4_fsblk_t)BLOCK_COST);
+	max_debt = EXT4_BLOCKS_PER_GROUP(sb);
+	sector_div(max_debt, max(blocks_per_dir, (ext4_fsblk_t)BLOCK_COST));
 	if (max_debt * INODE_COST > inodes_per_group)
 		max_debt = inodes_per_group / INODE_COST;
 	if (max_debt > 255)
diff -puN fs/ext4/resize.c~ext4_fsblk_sector_t fs/ext4/resize.c
--- linux-2.6.18-rc4/fs/ext4/resize.c~ext4_fsblk_sector_t	2006-08-09 15:41:51.536285953 -0700
+++ linux-2.6.18-rc4-ming/fs/ext4/resize.c	2006-08-09 15:41:51.556286115 -0700
@@ -36,7 +36,7 @@ static int verify_group_input(struct sup
 		 le16_to_cpu(es->s_reserved_gdt_blocks)) : 0;
 	ext4_fsblk_t metaend = start + overhead;
 	struct buffer_head *bh = NULL;
-	ext4_grpblk_t free_blocks_count;
+	ext4_grpblk_t free_blocks_count, offset;
 	int err = -EINVAL;
 
 	input->free_blocks_count = free_blocks_count =
@@ -49,13 +49,13 @@ static int verify_group_input(struct sup
 		       "no-super", input->group, input->blocks_count,
 		       free_blocks_count, input->reserved_blocks);
 
+	ext4_get_group_no_and_offset(sb, start, NULL, &offset);
 	if (group != sbi->s_groups_count)
 		ext4_warning(sb, __FUNCTION__,
 			     "Cannot add at group %u (only %lu groups)",
 			     input->group, sbi->s_groups_count);
-	else if ((start - le32_to_cpu(es->s_first_data_block)) %
-		 EXT4_BLOCKS_PER_GROUP(sb))
-		ext4_warning(sb, __FUNCTION__, "Last group not full");
+	else if (offset != 0)
+			ext4_warning(sb, __FUNCTION__, "Last group not full");
 	else if (input->reserved_blocks > input->blocks_count / 5)
 		ext4_warning(sb, __FUNCTION__, "Reserved blocks too high (%u)",
 			     input->reserved_blocks);
@@ -932,7 +932,7 @@ int ext4_group_extend(struct super_block
 
 	if (n_blocks_count > (sector_t)(~0ULL) >> (sb->s_blocksize_bits - 9)) {
 		printk(KERN_ERR "EXT4-fs: filesystem on %s:"
-			" too large to resize to %lu blocks safely\n",
+			" too large to resize to "E3FSBLK" blocks safely\n",
 			sb->s_id, n_blocks_count);
 		if (sizeof(sector_t) < 8)
 			ext4_warning(sb, __FUNCTION__,
@@ -947,8 +947,7 @@ int ext4_group_extend(struct super_block
 	}
 
 	/* Handle the remaining blocks in the last group only. */
-	last = (o_blocks_count - le32_to_cpu(es->s_first_data_block)) %
-		EXT4_BLOCKS_PER_GROUP(sb);
+	ext4_get_group_no_and_offset(sb, o_blocks_count, NULL, &last);
 
 	if (last == 0) {
 		ext4_warning(sb, __FUNCTION__,
diff -puN fs/ext4/super.c~ext4_fsblk_sector_t fs/ext4/super.c
--- linux-2.6.18-rc4/fs/ext4/super.c~ext4_fsblk_sector_t	2006-08-09 15:41:51.541285993 -0700
+++ linux-2.6.18-rc4-ming/fs/ext4/super.c	2006-08-09 15:41:51.560286147 -0700
@@ -1387,8 +1387,8 @@ static int ext4_fill_super (struct super
 	 * block sizes.  We need to calculate the offset from buffer start.
 	 */
 	if (blocksize != EXT4_MIN_BLOCK_SIZE) {
-		logic_sb_block = (sb_block * EXT4_MIN_BLOCK_SIZE) / blocksize;
-		offset = (sb_block * EXT4_MIN_BLOCK_SIZE) % blocksize;
+		logic_sb_block = sb_block * EXT4_MIN_BLOCK_SIZE;
+		offset = sector_div(logic_sb_block, blocksize);
 	} else {
 		logic_sb_block = sb_block;
 	}
@@ -1493,8 +1493,8 @@ static int ext4_fill_super (struct super
 
 		brelse (bh);
 		sb_set_blocksize(sb, blocksize);
-		logic_sb_block = (sb_block * EXT4_MIN_BLOCK_SIZE) / blocksize;
-		offset = (sb_block * EXT4_MIN_BLOCK_SIZE) % blocksize;
+		logic_sb_block = sb_block * EXT4_MIN_BLOCK_SIZE;
+		offset = sector_div(logic_sb_block, blocksize);
 		bh = sb_bread(sb, logic_sb_block);
 		if (!bh) {
 			printk(KERN_ERR
diff -puN include/linux/ext4_fs.h~ext4_fsblk_sector_t include/linux/ext4_fs.h
--- linux-2.6.18-rc4/include/linux/ext4_fs.h~ext4_fsblk_sector_t	2006-08-09 15:41:51.544286018 -0700
+++ linux-2.6.18-rc4-ming/include/linux/ext4_fs.h	2006-08-09 15:41:51.564286179 -0700
@@ -17,6 +17,7 @@
 #define _LINUX_EXT4_FS_H
 
 #include <linux/types.h>
+#include <linux/blkdev.h>
 
 /*
  * The second extended filesystem constants/structures
@@ -728,6 +729,27 @@ ext4_group_first_block_no(struct super_b
 #define ERR_BAD_DX_DIR	-75000
 
 /*
+ * This function calculate the block group number and offset,
+ * given a block number
+ */
+
+static inline void ext4_get_group_no_and_offset(struct super_block * sb,
+                                ext4_fsblk_t blocknr, unsigned long* blockgrpp,
+                                ext4_grpblk_t *offsetp)
+{
+        struct ext4_super_block *es = EXT4_SB(sb)->s_es;
+	ext4_grpblk_t offset;
+
+        blocknr = blocknr - le32_to_cpu(es->s_first_data_block);
+        offset = sector_div(blocknr, EXT4_BLOCKS_PER_GROUP(sb));
+	if (offsetp)
+		*offsetp = offset;
+	if (blockgrpp)
+	        *blockgrpp = blocknr;
+
+}
+
+/*
  * Function prototypes
  */
 
@@ -740,6 +762,10 @@ ext4_group_first_block_no(struct super_b
 # define NORET_AND     noreturn,
 
 /* balloc.c */
+extern unsigned int ext4_block_group(struct super_block *sb,
+			ext4_fsblk_t blocknr);
+extern ext4_grpblk_t ext4_block_group_offset(struct super_block *sb,
+			ext4_fsblk_t blocknr);
 extern int ext4_bg_has_super(struct super_block *sb, int group);
 extern unsigned long ext4_bg_num_gdb(struct super_block *sb, int group);
 extern ext4_fsblk_t ext4_new_block (handle_t *handle, struct inode *inode,
diff -puN include/linux/ext4_fs_i.h~ext4_fsblk_sector_t include/linux/ext4_fs_i.h
--- linux-2.6.18-rc4/include/linux/ext4_fs_i.h~ext4_fsblk_sector_t	2006-08-09 15:41:51.548286050 -0700
+++ linux-2.6.18-rc4-ming/include/linux/ext4_fs_i.h	2006-08-09 15:41:51.564286179 -0700
@@ -25,9 +25,9 @@
 typedef int ext4_grpblk_t;
 
 /* data type for filesystem-wide blocks number */
-typedef unsigned long ext4_fsblk_t;
+typedef sector_t ext4_fsblk_t;
 
-#define E3FSBLK "%lu"
+#define E3FSBLK SECTOR_FMT
 
 struct ext4_reserve_window {
 	ext4_fsblk_t	_rsv_start;	/* First byte reserved */

_



-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH 3/9] support >32 bit ext4 filesystem block type in kernel
  2006-08-10  1:21 [PATCH 3/9] support >32 bit ext4 filesystem block type in kernel Mingming Cao
@ 2006-08-10  6:40 ` Andrew Morton
  2006-08-10 17:19   ` Mingming Cao
  0 siblings, 1 reply; 3+ messages in thread
From: Andrew Morton @ 2006-08-10  6:40 UTC (permalink / raw)
  To: cmm; +Cc: linux-fsdevel, ext2-devel, linux-kernel

On Wed, 09 Aug 2006 18:21:00 -0700
Mingming Cao <cmm@us.ibm.com> wrote:

> 
> Redefine ext4 in-kernel filesystem block type (ext4_fsblk_t) from unsigned
> long to sector_t, to allow kernel to handle  >32 bit ext4 blocks.
> 

I don't get it.

Randomly-chosen snippet:

> @@ -274,7 +274,8 @@ static int find_group_orlov(struct super
>  	freei = percpu_counter_read_positive(&sbi->s_freeinodes_counter);
>  	avefreei = freei / ngroups;
>  	freeb = percpu_counter_read_positive(&sbi->s_freeblocks_counter);
> -	avefreeb = freeb / ngroups;
> +	avefreeb = freeb;
> +	sector_div(avefreeb, ngroups);
>  	ndirs = percpu_counter_read_positive(&sbi->s_dirs_counter);
>  
>  	if ((parent == sb->s_root->d_inode) ||

Here, `avefreeb' is still a 32-bit type.  Why feed it into sector_div()?

> @@ -303,13 +304,15 @@ static int find_group_orlov(struct super
>  		goto fallback;
>  	}
>  
> -	blocks_per_dir = (le32_to_cpu(es->s_blocks_count) - freeb) / ndirs;
> +	blocks_per_dir = le32_to_cpu(es->s_blocks_count) - freeb;
> +	sector_div(blocks_per_dir, ndirs);

And here le32_to_cpu() is very much a 32-bit type.  Why sector_div()?

And I agree with me: we want to get all the sector_t's out of this
filesystem.  unsigned long long, do_div()?


-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH 3/9] support >32 bit ext4 filesystem block type in kernel
  2006-08-10  6:40 ` Andrew Morton
@ 2006-08-10 17:19   ` Mingming Cao
  0 siblings, 0 replies; 3+ messages in thread
From: Mingming Cao @ 2006-08-10 17:19 UTC (permalink / raw)
  To: Andrew Morton; +Cc: linux-kernel, ext2-devel, linux-fsdevel

Andrew Morton wrote:
> On Wed, 09 Aug 2006 18:21:00 -0700
> Mingming Cao <cmm@us.ibm.com> wrote:
> 
> 
>>Redefine ext4 in-kernel filesystem block type (ext4_fsblk_t) from unsigned
>>long to sector_t, to allow kernel to handle  >32 bit ext4 blocks.
>>
> 
> 
> I don't get it.

The intention is able to support 48bit ext4 on 64bit and 32bit arch 
whenevern CONFIG_LBD is enabled (or when sector_t is actually 64 bit). 
It just seems waste of memory to support 48bit in-kernel ext4 blks on 32 
bit if CONFIG_LBD is disabled, since we won't support large device anyway.

ext3_fsblk_t was a unsigned long type before, which is always 32bit on 
32bit arch. Thus we convert the ext3_fsblk_t to sector_t and depend on 
CONFIG_LBD to decide whether we need 48bit in-kernel variables.(on-disk 
block numbers are always 48 bit).

> 
> Randomly-chosen snippet:
> 
> 
>>@@ -274,7 +274,8 @@ static int find_group_orlov(struct super
>> 	freei = percpu_counter_read_positive(&sbi->s_freeinodes_counter);
>> 	avefreei = freei / ngroups;
>> 	freeb = percpu_counter_read_positive(&sbi->s_freeblocks_counter);
>>-	avefreeb = freeb / ngroups;
>>+	avefreeb = freeb;
>>+	sector_div(avefreeb, ngroups);
>> 	ndirs = percpu_counter_read_positive(&sbi->s_dirs_counter);
>> 
>> 	if ((parent == sb->s_root->d_inode) ||
> 
> 
> Here, `avefreeb' is still a 32-bit type.  Why feed it into sector_div()?
> 
avefreeb is ext3_fsblk_t type(sector_t type), which is 64bit on 64bit 
arch and 64bit on 32bit arch if CONFIG_LBD is enabled.

> 
>>@@ -303,13 +304,15 @@ static int find_group_orlov(struct super
>> 		goto fallback;
>> 	}
>> 
>>-	blocks_per_dir = (le32_to_cpu(es->s_blocks_count) - freeb) / ndirs;
>>+	blocks_per_dir = le32_to_cpu(es->s_blocks_count) - freeb;
>>+	sector_div(blocks_per_dir, ndirs);
> 
> 
> And here le32_to_cpu() is very much a 32-bit type.  Why sector_div()?

ah, sorry about the confusing, s_blocks_count (the number of blocks on 
this fs, on-disk) should be always 48bit value, and should not use 
le32_to_cpu() to read-in. That is being fixed in [patch 9/9] 64bit 
metadata support,  where we convert 32 bit s_blocks_count to sector_t, 
and also use mixro EXT4_BLOCKS_COUN(es) to read in the blocks count:

@@ -304,7 +306,7 @@ static int find_group_orlov(struct super
  		goto fallback;
  	}

-	blocks_per_dir = le32_to_cpu(es->s_blocks_count) - freeb;
+	blocks_per_dir = EXT4_BLOCKS_COUNT(es) - freeb;

This patch[3/9] is just fix the in-kernel blocks type...We trying to do 
this incrementally: first, support in-kernel blocks type >32bit, then 
change the on-disk blocks type to >32bit.

> 
> And I agree with me: we want to get all the sector_t's out of this
> filesystem.  unsigned long long, do_div()?
> 

Thanks,Mingming


^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2006-08-10 17:19 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-08-10  1:21 [PATCH 3/9] support >32 bit ext4 filesystem block type in kernel Mingming Cao
2006-08-10  6:40 ` Andrew Morton
2006-08-10 17:19   ` Mingming Cao

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).