diff mbox

allow goal inode to be specified

Message ID 20090610202702.GI9002@webber.adilger.int
State Accepted, archived
Headers show

Commit Message

Andreas Dilger June 10, 2009, 8:27 p.m. UTC
Allow a goal inode to be specified when allocating new inodes.
If the goal is within the range of valid inodes use this in
preference to one of the other target inode heuristics (Orlov or
parent directory).

The goal inode can be specified via /sys/fs/{dev}/inode_goal for
testing inode allocation beyond 2^32 blocks on very large filesystems,
and in the future will be used for large xattr inode allocation.

Signed-off-by: Andreas Dilger <adilger@sun.com>


Cheers, Andreas
--
Andreas Dilger
Sr. Staff Engineer, Lustre Group
Sun Microsystems of Canada, Inc.

--
To unsubscribe from this list: send the line "unsubscribe linux-ext4" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Comments

Theodore Ts'o June 13, 2009, 3:48 p.m. UTC | #1
On Wed, Jun 10, 2009 at 02:27:02PM -0600, Andreas Dilger wrote:
> Allow a goal inode to be specified when allocating new inodes.
> If the goal is within the range of valid inodes use this in
> preference to one of the other target inode heuristics (Orlov or
> parent directory).
> 
> The goal inode can be specified via /sys/fs/{dev}/inode_goal for
> testing inode allocation beyond 2^32 blocks on very large filesystems,
> and in the future will be used for large xattr inode allocation.

This patch didn't quite apply against the mainline ext4, and in
addition it conflicted with a patch to keep the choice of Orlov topdir
inode numbers stable for the purposes of benchmarking.  So instead I
dropped the following two patches into the ext4 patch queue.

	    	      	  	       	   	- Ted
--
To unsubscribe from this list: send the line "unsubscribe linux-ext4" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

Index: linux-stage/fs/ext4/ialloc.c
===================================================================
--- linux-stage.orig/fs/ext4/ialloc.c
+++ linux-stage/fs/ext4/ialloc.c
@@ -675,7 +675,8 @@  err_ret:
  * For other inodes, search forward from the parent directory's block
  * group to find a free inode.
  */
-struct inode *ext4_new_inode(handle_t *handle, struct inode *dir, int mode)
+struct inode *ext4_new_inode_goal(handle_t *handle, struct inode *dir,
+				  int mode, unsigned goal)
 {
 	struct super_block *sb;
 	struct buffer_head *inode_bitmap_bh = NULL;
@@ -706,6 +707,14 @@  struct inode *ext4_new_inode(handle_t *h
 	sbi = EXT4_SB(sb);
 	es = sbi->s_es;
 
+	if (goal && goal < le32_to_cpu(es->s_inodes_count)) {
+		group = (goal - 1) / EXT4_INODES_PER_GROUP(sb);
+		ino = (goal - 1) % EXT4_INODES_PER_GROUP(sb);
+
+		ret2 = 0;
+		goto got_group;
+	}
+
 	if (sbi->s_log_groups_per_flex && test_opt(sb, OLDALLOC)) {
 		ret2 = find_group_flex(sb, dir, &group);
 		if (ret2 == -1) {
@@ -724,7 +733,7 @@  got_group:
 	if (ret2 == -1)
 		goto out;
 
-	for (i = 0; i < sbi->s_groups_count; i++) {
+	for (i = 0; i < sbi->s_groups_count; i++, ino = 0) {
 		err = -EIO;
 
 		gdp = ext4_get_group_desc(sb, group, &group_desc_bh);
@@ -736,8 +745,6 @@  got_group:
 		if (!inode_bitmap_bh)
 			goto fail;
 
-		ino = 0;
-
 repeat_in_this_group:
 		ino = ext4_find_next_zero_bit((unsigned long *)
 					      inode_bitmap_bh->b_data,
Index: linux-stage/fs/ext4/ext4.h
===================================================================
--- linux-stage.orig/fs/ext4/ext4.h
+++ linux-stage/fs/ext4/ext4.h
@@ -1032,7 +1032,14 @@  extern int ext4fs_dirhash(const char *na
 			  dx_hash_info *hinfo);
 
 /* ialloc.c */
-extern struct inode * ext4_new_inode(handle_t *, struct inode *, int);
+extern struct inode *ext4_new_inode_goal(handle_t *handle, struct inode *dir,
+				    int mode, unsigned goal);
+static inline struct inode *ext4_new_inode(handle_t *handle, struct inode *dir,
+					   int mode)
+{
+	return ext4_new_inode_goal(handle, dir, mode,
+				   EXT4_SB(dir->i_sb)->s_inode_goal);
+}
 extern void ext4_free_inode(handle_t *, struct inode *);
 extern struct inode * ext4_orphan_get(struct super_block *, unsigned long);
 extern unsigned long ext4_count_free_inodes(struct super_block *);
Index: linux-stage/fs/ext4/super.c
===================================================================
--- linux-stage.orig/fs/ext4/super.c
+++ linux-stage/fs/ext4/super.c
@@ -2145,6 +2145,7 @@ 
 EXT4_RO_ATTR(lifetime_write_kbytes);
 EXT4_ATTR_OFFSET(inode_readahead_blks, 0644, sbi_ui_show,
 		 inode_readahead_blks_store, s_inode_readahead_blks);
+EXT4_RW_ATTR_SBI_UI(inode_goal, s_inode_goal);
 EXT4_RW_ATTR_SBI_UI(mb_stats, s_mb_stats);
 EXT4_RW_ATTR_SBI_UI(mb_max_to_scan, s_mb_max_to_scan);
 EXT4_RW_ATTR_SBI_UI(mb_min_to_scan, s_mb_min_to_scan);
@@ -2157,6 +2158,7 @@ 
 	ATTR_LIST(session_write_kbytes),
 	ATTR_LIST(lifetime_write_kbytes),
 	ATTR_LIST(inode_readahead_blks),
+	ATTR_LIST(inode_goal),
 	ATTR_LIST(mb_stats),
 	ATTR_LIST(mb_max_to_scan),
 	ATTR_LIST(mb_min_to_scan),
Index: linux-stage/fs/ext4/ext4_sb.h
===================================================================
--- linux-stage.orig/fs/ext4/ext4_sb.h
+++ linux-stage/fs/ext4/ext4_sb.h
@@ -53,6 +53,7 @@  struct ext4_sb_info {
 	int s_inode_size;
 	int s_first_ino;
 	unsigned int s_inode_readahead_blks;
+	unsigned int s_inode_goal;
 	spinlock_t s_next_gen_lock;
 	u32 s_next_generation;
 	u32 s_hash_seed[4];