[Ocfs2-tools-commits] zab commits r446 - in trunk: fsck.ocfs2 libocfs2 libocfs2/include tunefs.ocfs2

svn-commits at oss.oracle.com svn-commits at oss.oracle.com
Wed Dec 1 19:42:14 CST 2004


Author: zab
Date: 2004-12-01 19:42:12 -0600 (Wed, 01 Dec 2004)
New Revision: 446

Modified:
   trunk/fsck.ocfs2/pass3.c
   trunk/libocfs2/alloc.c
   trunk/libocfs2/bitmap.c
   trunk/libocfs2/chainalloc.c
   trunk/libocfs2/expanddir.c
   trunk/libocfs2/extend_file.c
   trunk/libocfs2/include/bitmap.h
   trunk/libocfs2/include/ocfs2.h
   trunk/libocfs2/newdir.c
   trunk/libocfs2/ocfs2_err.et.in
   trunk/tunefs.ocfs2/tunefs.c
Log:
get fsck adding lost+found.

o ensure that /lost+found exists in pass 3
o expand_dir: point ".." at the parent, set file_type, update the parent's
  link_count, pay the ocfs2_free debugging tax
o add range allocation and clearing to the bitmaps
o add ocfs2_{new,free}_clusters wrappers around range ops on the bitmap chain
o have extend_allocation grow the alloc in single cluster chunks :/
o set i_fs_generation when initializing an inode
o add ocfs2_chain_add_group() to add a desc to chain 0 of an allocator
o teach new_inode to grow node 0's inode allocator chain if the first
  attempt fails
o get rid of the chainalloc_find_desc business, the bitmap change callbacks
  seem to do what it was trying to do?


Modified: trunk/fsck.ocfs2/pass3.c
===================================================================
--- trunk/fsck.ocfs2/pass3.c	2004-12-02 01:17:44 UTC (rev 445)
+++ trunk/fsck.ocfs2/pass3.c	2004-12-02 01:42:12 UTC (rev 446)
@@ -40,6 +40,8 @@
 #include "problem.h"
 #include "util.h"
 
+static char *whoami = "pass3";
+
 static void check_root(o2fsck_state *ost)
 {
 	int was_set;
@@ -70,6 +72,62 @@
 	 * in used, dir bitmaps. */
 }
 
+static void check_lostfound(o2fsck_state *ost)
+{
+	char name[] = "lost+found";
+	int namelen = sizeof(name) - 1;
+	uint64_t blkno = 0;
+	errcode_t ret;
+
+	ret = ocfs2_lookup(ost->ost_fs, ost->ost_fs->fs_root_blkno, name,
+			   namelen, NULL, &blkno);
+	if (ret == 0)
+		return;
+
+	if (!prompt(ost, PY, 0, "/lost+found does not exist.  Create it so "
+		    "that we an possibly fill it with orphaned inodes?"))
+		return;
+
+	blkno = 0;
+	ret = ocfs2_new_inode(ost->ost_fs, &blkno, 0755 | S_IFDIR);
+	if (ret) {
+		com_err(whoami, ret, "while trying to allocate a new inode "
+			"for /lost+found");
+		return;
+	}
+
+	ret = ocfs2_expand_dir(ost->ost_fs, blkno, ost->ost_fs->fs_root_blkno);
+	if (ret) {
+		com_err(whoami, ret, "while trying to expand a new "
+			"/lost+found directory");
+		goto out;
+	}
+
+	/* XXX expand_dir itself will leak added dir blocks in some error
+	 * paths so we don't bother trying to clean them up either */
+	ret = ocfs2_link(ost->ost_fs, ost->ost_fs->fs_root_blkno, name, blkno,
+			 OCFS2_FT_DIR);
+	if (ret) {
+		com_err(whoami, ret, "while linking inode %"PRIu64" as "
+			"/lost+found", blkno);
+		goto out;
+	}
+
+	blkno = 0;
+
+	/* set both icount refs to 2.  add dir info for it.  put it 
+	 * in used, dir bitmaps. */
+out:
+	if (blkno) {
+		ret = ocfs2_delete_inode(ost->ost_fs, blkno);
+		if (ret) {
+			com_err(whoami, ret, "while trying to clean up an "
+			        "an allocated inode after linking /lost+found "
+				"failed");
+		}
+	}
+}
+
 struct fix_dot_dot_args {
 	o2fsck_state	*ost;
 	uint64_t	parent;
@@ -216,6 +274,7 @@
 	 * other required directories like root here */
 
 	check_root(ost);
+	check_lostfound(ost);
 
 	dp = o2fsck_dir_parent_lookup(&ost->ost_dir_parents, 
 					ost->ost_fs->fs_root_blkno);

Modified: trunk/libocfs2/alloc.c
===================================================================
--- trunk/libocfs2/alloc.c	2004-12-02 01:17:44 UTC (rev 445)
+++ trunk/libocfs2/alloc.c	2004-12-02 01:42:12 UTC (rev 446)
@@ -102,6 +102,7 @@
 	ocfs2_extent_list *fel;
 
 	di->i_generation = fs->fs_super->i_generation;
+	di->i_fs_generation = fs->fs_super->i_generation;
 	di->i_blkno = blkno;
 	di->i_suballoc_node = node;
 	di->i_suballoc_bit = (uint16_t)(blkno - gd_blkno);
@@ -142,15 +143,22 @@
 	if (ret)
 		return ret;
 
-	ret = ocfs2_load_allocator(fs, INODE_ALLOC_SYSTEM_INODE,
-			   	   0, &fs->fs_inode_allocs[0]);
+	ret = ocfs2_load_allocator(fs, INODE_ALLOC_SYSTEM_INODE, 0,
+				   &fs->fs_inode_allocs[0]);
 	if (ret)
 		goto out;
 
 	ret = ocfs2_chain_alloc_with_io(fs, fs->fs_inode_allocs[0],
 					&gd_blkno, ino);
-	if (ret)
-		goto out;
+	if (ret == OCFS2_ET_BIT_NOT_FOUND) {
+		ret = ocfs2_chain_add_group(fs, fs->fs_inode_allocs[0]);
+		if (ret)
+			goto out;
+		ret = ocfs2_chain_alloc_with_io(fs, fs->fs_inode_allocs[0],
+						&gd_blkno, ino);
+		if (ret)
+			goto out;
+	}
 
 	memset(buf, 0, fs->fs_blocksize);
 	di = (ocfs2_dinode *)buf;
@@ -158,6 +166,8 @@
 	ocfs2_init_inode(fs, di, 0, gd_blkno, *ino);
 
 	ret = ocfs2_write_inode(fs, *ino, buf);
+	if (ret)
+		ocfs2_delete_inode(fs, *ino);
 
 out:
 	ocfs2_free(&buf);
@@ -337,7 +347,6 @@
 	return ret;
 }
 
-#if 0
 /* This function needs to be filled out.  Essentially, it should be
  * calling a function in chainalloc.c.  Something like
  * "ocfs2_chain_alloc_range()".  The difference between that and
@@ -345,13 +354,58 @@
  * That function should take a 'required' number of bits, and return
  * the biggest chunk available.  It will need some sort of
  * "find_clear_bit_range()" function for the bitmaps.
+ *
+ * XXX what to do about local allocs?
  */
-errcode_t ocfs2_new_clusters()
+errcode_t ocfs2_new_clusters(ocfs2_filesys *fs,
+			     uint32_t requested,
+			     uint64_t *start_blkno)
 {
-	return 0;
+	errcode_t ret;
+	uint64_t start_bit;
+
+	ret = ocfs2_load_allocator(fs, GLOBAL_BITMAP_SYSTEM_INODE,
+				   0, &fs->fs_cluster_alloc);
+	if (ret)
+		goto out;
+
+	ret = ocfs2_chain_alloc_range(fs, fs->fs_cluster_alloc, requested,
+				      &start_bit);
+	if (ret)
+		goto out;
+
+	*start_blkno = ocfs2_clusters_to_blocks(fs, start_bit);
+
+	ret = ocfs2_write_chain_allocator(fs, fs->fs_cluster_alloc);
+	if (ret)
+		ocfs2_free_clusters(fs, requested, *start_blkno);
+
+out:
+	return ret;
 }
-#endif
 
+errcode_t ocfs2_free_clusters(ocfs2_filesys *fs,
+			      uint64_t len,
+			      uint64_t start_blkno)
+{
+	errcode_t ret;
+
+	ret = ocfs2_load_allocator(fs, GLOBAL_BITMAP_SYSTEM_INODE,
+				   0, &fs->fs_cluster_alloc);
+	if (ret)
+		goto out;
+
+	ret = ocfs2_chain_free_range(fs, fs->fs_cluster_alloc, len,
+				     ocfs2_blocks_to_clusters(fs, start_blkno));
+	if (ret)
+		goto out;
+
+	/* XXX OK, it's bad if we can't revert this after the io fails */
+	ret = ocfs2_write_chain_allocator(fs, fs->fs_cluster_alloc);
+out:
+	return ret;
+}
+
 #ifdef DEBUG_EXE
 #include <stdio.h>
 

Modified: trunk/libocfs2/bitmap.c
===================================================================
--- trunk/libocfs2/bitmap.c	2004-12-02 01:17:44 UTC (rev 445)
+++ trunk/libocfs2/bitmap.c	2004-12-02 01:42:12 UTC (rev 446)
@@ -137,6 +137,25 @@
 	return (*bitmap->b_ops->find_next_clear)(bitmap, start, found);
 }
 
+/* kind of poorly named, but I couldn't come up with something nicer */
+errcode_t ocfs2_bitmap_alloc_range(ocfs2_bitmap *bitmap, uint64_t len, 
+				   uint64_t *first_bit)
+{
+	if (len == 0 || len >= bitmap->b_total_bits)
+		return OCFS2_ET_INVALID_ARGUMENT;
+
+	return (*bitmap->b_ops->alloc_range)(bitmap, len, first_bit);
+}
+
+errcode_t ocfs2_bitmap_clear_range(ocfs2_bitmap *bitmap, uint64_t len, 
+				   uint64_t first_bit)
+{
+	if (len == 0 || len + first_bit > bitmap->b_total_bits)
+		return OCFS2_ET_INVALID_ARGUMENT;
+
+	return (*bitmap->b_ops->clear_range)(bitmap, len, first_bit);
+}
+
 errcode_t ocfs2_bitmap_read(ocfs2_bitmap *bitmap)
 {
 	if (!bitmap->b_ops->read_bitmap)
@@ -288,6 +307,10 @@
 		br = rb_entry(node, struct ocfs2_bitmap_region, br_node);
 
 		ret = func(br, private_data);
+		if (ret == OCFS2_ET_ITERATION_COMPLETE) {
+			ret = 0;
+			break;
+		}
 		if (ret)
 			break;
 	}
@@ -452,7 +475,22 @@
 	return 0;
 }
 
+static int set_generic_shared(ocfs2_bitmap *bitmap, 
+			      struct ocfs2_bitmap_region *br,
+			      uint64_t bitno)
+{
+	int old_tmp;
 
+	old_tmp = ocfs2_set_bit(bitno - br->br_start_bit, br->br_bitmap);
+	if (!old_tmp) {
+		br->br_set_bits++;
+		if (bitmap->b_ops->bit_change_notify)
+			(*bitmap->b_ops->bit_change_notify)(bitmap, br, bitno,
+							    1);
+	}
+	return old_tmp;
+}
+
 /*
  * Helper functions for the most generic of bitmaps.  If there is no
  * memory allocated for the bit, it fails.
@@ -467,19 +505,29 @@
 	if (!br)
 		return OCFS2_ET_INVALID_BIT;
 
-	old_tmp = ocfs2_set_bit(bitno - br->br_start_bit,
-				br->br_bitmap);
+	old_tmp = set_generic_shared(bitmap, br, bitno);
 	if (oldval)
 		*oldval = old_tmp;
 
-	if (!old_tmp) {
-		br->br_set_bits++;
+	return 0;
+}
+
+static int clear_generic_shared(ocfs2_bitmap *bitmap, 
+				struct ocfs2_bitmap_region *br,
+				uint64_t bitno)
+{
+	int old_tmp;
+
+	old_tmp = ocfs2_clear_bit(bitno - br->br_start_bit,
+				  br->br_bitmap);
+	if (old_tmp) {
+		br->br_set_bits--;
 		if (bitmap->b_ops->bit_change_notify)
 			(*bitmap->b_ops->bit_change_notify)(bitmap, br, bitno,
-							    1);
+							    0);
 	}
 
-	return 0;
+	return old_tmp;
 }
 
 errcode_t ocfs2_bitmap_clear_generic(ocfs2_bitmap *bitmap,
@@ -492,18 +540,10 @@
 	if (!br)
 		return OCFS2_ET_INVALID_BIT;
 
-	old_tmp = ocfs2_clear_bit(bitno - br->br_start_bit,
-				  br->br_bitmap);
+	old_tmp = clear_generic_shared(bitmap, br, bitno);
 	if (oldval)
 		*oldval = old_tmp;
 
-	if (old_tmp) {
-		br->br_set_bits--;
-		if (bitmap->b_ops->bit_change_notify)
-			(*bitmap->b_ops->bit_change_notify)(bitmap, br, bitno,
-							    0);
-	}
-
 	return 0;
 }
 
@@ -589,7 +629,96 @@
 	return OCFS2_ET_BIT_NOT_FOUND;
 }
 
+struct alloc_range_args {
+	ocfs2_bitmap	*ar_bitmap;
+	uint64_t	ar_len;
+	uint64_t	ar_first_bit;
+	errcode_t	ar_ret;
+};
 
+static errcode_t alloc_range_func(struct ocfs2_bitmap_region *br,
+				  void *private_data)
+{
+	struct alloc_range_args *ar = private_data;
+	errcode_t ret = 0;
+	int start, end;
+
+	if ((br->br_total_bits - br->br_set_bits) < ar->ar_len)
+		goto out;
+
+	for (start = 0; start + ar->ar_len <= br->br_total_bits; ) {
+		start = ocfs2_find_next_bit_clear(br->br_bitmap,
+						  br->br_total_bits,
+						  start);
+		if (start == br->br_total_bits)
+			goto out;
+
+		/* avoiding start + 1 here so that start at total_bits - 1
+		 * just works out */
+		end = ocfs2_find_next_bit_set(br->br_bitmap,
+					      br->br_total_bits,
+					      start);
+		if ((end - start) < ar->ar_len) {
+			start = end + 1;
+			continue;
+		}
+
+		if ((end - start) > ar->ar_len)
+			end = start + ar->ar_len;
+
+		ar->ar_first_bit = br->br_start_bit + start;
+		for (; start < end; start++)
+			set_generic_shared(ar->ar_bitmap, br,
+					   start + br->br_start_bit);
+
+		ar->ar_ret = 0;
+		ret = OCFS2_ET_ITERATION_COMPLETE;
+		break;
+	}
+
+out:
+	return ret;
+}
+
+errcode_t ocfs2_bitmap_alloc_range_generic(ocfs2_bitmap *bitmap,
+					   uint64_t len,
+					   uint64_t *first_bit)
+{
+	errcode_t ret;
+	struct alloc_range_args ar = { 
+		.ar_bitmap = bitmap,
+		.ar_len = len,
+		.ar_ret = OCFS2_ET_BIT_NOT_FOUND,
+	};
+
+	ret = ocfs2_bitmap_foreach_region(bitmap, alloc_range_func,
+					  &ar);
+	if (ret == 0)
+		ret = ar.ar_ret;
+
+	if (ret == 0)
+		*first_bit = ar.ar_first_bit;
+
+	return ret;
+}
+
+errcode_t ocfs2_bitmap_clear_range_generic(ocfs2_bitmap *bitmap,
+					   uint64_t len,
+					   uint64_t first_bit)
+{
+	struct ocfs2_bitmap_region *br;
+	uint64_t end;
+
+	br = ocfs2_bitmap_lookup(bitmap, first_bit, len, NULL, NULL, NULL);
+	if (!br)
+		return OCFS2_ET_INVALID_BIT;
+
+	for (end = first_bit + len; first_bit < end; first_bit++)
+		clear_generic_shared(bitmap, br, first_bit + br->br_start_bit);
+
+	return 0;
+}
+
 /*
  * Helper functions for a bitmap with holes in it.
  * If a bit doesn't have memory allocated for it, we allocate.
@@ -702,6 +831,8 @@
 	.test_bit		= ocfs2_bitmap_test_generic,
 	.find_next_set		= ocfs2_bitmap_find_next_set_generic,
 	.find_next_clear	= ocfs2_bitmap_find_next_clear_generic,
+	.alloc_range		= ocfs2_bitmap_alloc_range_generic,
+	.clear_range		= ocfs2_bitmap_clear_range_generic,
 };
 
 errcode_t ocfs2_cluster_bitmap_new(ocfs2_filesys *fs,
@@ -759,6 +890,8 @@
 	.test_bit		= ocfs2_bitmap_test_holes,
 	.find_next_set		= ocfs2_bitmap_find_next_set_holes,
 	.find_next_clear	= ocfs2_bitmap_find_next_clear_holes,
+	/* XXX can't allocate a range yet, would need to fill holes and merge
+	 * with adjacent */
 };
 
 errcode_t ocfs2_block_bitmap_new(ocfs2_filesys *fs,

Modified: trunk/libocfs2/chainalloc.c
===================================================================
--- trunk/libocfs2/chainalloc.c	2004-12-02 01:17:44 UTC (rev 445)
+++ trunk/libocfs2/chainalloc.c	2004-12-02 01:42:12 UTC (rev 446)
@@ -256,6 +256,8 @@
 	.write_bitmap		= chainalloc_write_bitmap,
 	.destroy_notify		= chainalloc_destroy_notify,
 	.bit_change_notify	= chainalloc_bit_change_notify,
+	.alloc_range		= ocfs2_bitmap_alloc_range_generic,
+	.clear_range		= ocfs2_bitmap_clear_range_generic,
 };
 
 static errcode_t ocfs2_chainalloc_bitmap_new(ocfs2_filesys *fs,
@@ -335,28 +337,31 @@
 	return ocfs2_bitmap_write(cinode->ci_chains);
 }
 
-struct find_desc_ctxt {
-	uint64_t target_bit;
-	uint64_t gd_blkno;
-};
+/* FIXME: should take a hint, no? */
+/* FIXME: Better name, too */
+errcode_t ocfs2_chain_alloc_range(ocfs2_filesys *fs,
+				  ocfs2_cached_inode *cinode,
+				  uint64_t requested,
+				  uint64_t *start_bit)
+{
+	if (!cinode->ci_chains)
+		return OCFS2_ET_INVALID_ARGUMENT;
 
-static errcode_t chainalloc_find_desc(struct ocfs2_bitmap_region *br,
-				      void *private_data)
+	return ocfs2_bitmap_alloc_range(cinode->ci_chains, requested,
+				        start_bit);
+}
+
+errcode_t ocfs2_chain_free_range(ocfs2_filesys *fs,
+				 ocfs2_cached_inode *cinode,
+				 uint64_t len,
+				 uint64_t start_bit)
 {
-	struct chainalloc_region_private *cr = br->br_private;
-	struct find_desc_ctxt *ctxt = private_data;
+	if (!cinode->ci_chains)
+		return OCFS2_ET_INVALID_ARGUMENT;
 
-	if (ctxt->target_bit < br->br_start_bit)
-		return 0;
-	if (ctxt->target_bit >= (br->br_start_bit + br->br_total_bits))
-		return 0;
-
-	ctxt->gd_blkno = cr->cr_ag->bg_blkno;
-	return 0;
+	return ocfs2_bitmap_clear_range(cinode->ci_chains, len, start_bit);
 }
 
-/* FIXME: should take a hint, no? */
-/* FIXME: Better name, too */
 errcode_t ocfs2_chain_alloc(ocfs2_filesys *fs,
 			    ocfs2_cached_inode *cinode,
 			    uint64_t *gd_blkno,
@@ -364,7 +369,6 @@
 {
 	errcode_t ret;
 	int oldval;
-	struct find_desc_ctxt ctxt;
 
 	if (!cinode->ci_chains)
 		return OCFS2_ET_INVALID_ARGUMENT;
@@ -373,12 +377,6 @@
 	if (ret)
 		return ret;
 
-	ctxt.gd_blkno = 0;
-	ctxt.target_bit = *bitno;
-	ret = ocfs2_bitmap_foreach_region(cinode->ci_chains,
-					  chainalloc_find_desc, &ctxt);
-	*gd_blkno = ctxt.gd_blkno;
-
 	ret = ocfs2_bitmap_set(cinode->ci_chains, *bitno, &oldval);
 	if (ret)
 		return ret;
@@ -459,6 +457,91 @@
 	gd->bg_free_bits_count = gd->bg_bits - 1;
 }
 
+errcode_t ocfs2_chain_add_group(ocfs2_filesys *fs,
+				ocfs2_cached_inode *cinode)
+{
+	errcode_t ret;
+	uint64_t blkno = 0, old_blkno = 0;
+	ocfs2_group_desc *gd;
+	char *buf = NULL;
+	ocfs2_chain_rec *rec = NULL;
+	struct chainalloc_bitmap_private *cb = cinode->ci_chains->b_private;
+
+	ret = ocfs2_malloc_block(fs->fs_io, &buf);
+	if (ret)
+		return ret;
+	gd = (ocfs2_group_desc *)buf;
+
+	ret = ocfs2_new_clusters(fs, cinode->ci_inode->id2.i_chain.cl_cpg,
+				 &blkno);
+	if (ret)
+		goto out;
+
+	ocfs2_init_group_desc(fs, gd, blkno, fs->fs_super->i_fs_generation,
+			      cinode->ci_inode->i_blkno,
+			      cinode->ci_inode->id2.i_chain.cl_cpg *
+			      cinode->ci_inode->id2.i_chain.cl_bpc, 0);
+
+	ret = ocfs2_write_group_desc(fs, blkno, (char *)gd);
+	if (ret)
+		goto out;
+
+	/* XXX could be a helper? */
+	rec = &cinode->ci_inode->id2.i_chain.cl_recs[0];
+	rec->c_free += gd->bg_free_bits_count;
+	rec->c_total += gd->bg_bits;
+	old_blkno = rec->c_blkno;
+	rec->c_blkno = blkno;
+
+	cinode->ci_inode->i_clusters += cinode->ci_inode->id2.i_chain.cl_cpg;
+	cinode->ci_inode->id1.bitmap1.i_total += gd->bg_bits;
+	cinode->ci_inode->id1.bitmap1.i_used += gd->bg_bits -
+						gd->bg_free_bits_count;
+	if (cinode->ci_inode->id2.i_chain.cl_next_free_rec == 0)
+		cinode->ci_inode->id2.i_chain.cl_next_free_rec = 1;
+
+	ret = ocfs2_write_cached_inode(fs, cinode);
+	if (ret)
+		goto out;
+
+	/* XXX this is probably too clever by half */ 
+	ret = chainalloc_process_group(fs, blkno, 0, cinode->ci_chains);
+	if (ret) {
+		ret = cb->cb_errcode;
+		goto out;
+	}
+
+	/* ok, it's official */
+	blkno = 0;
+	rec = NULL;
+
+out:
+	if (rec != NULL) {
+		/* XXX also could be a helper */
+		rec->c_free -= gd->bg_free_bits_count;
+		rec->c_total -= gd->bg_bits;
+		rec->c_blkno = old_blkno;
+
+		cinode->ci_inode->i_clusters -= 
+			cinode->ci_inode->id2.i_chain.cl_cpg;
+		cinode->ci_inode->id1.bitmap1.i_total -= gd->bg_bits;
+		cinode->ci_inode->id1.bitmap1.i_used -= gd->bg_bits -
+							gd->bg_free_bits_count;
+		if (cinode->ci_inode->id2.i_chain.cl_next_free_rec == 1 &&
+		    old_blkno == 0)
+			cinode->ci_inode->id2.i_chain.cl_next_free_rec = 0;
+
+		ocfs2_write_cached_inode(fs, cinode);
+	}
+	if (blkno != 0)
+		ocfs2_free_clusters(fs, cinode->ci_inode->id2.i_chain.cl_cpg,
+				    blkno);
+	if (buf)
+		ocfs2_free(&buf);
+
+	return ret;
+}
+
 #ifdef DEBUG_EXE
 #include <stdlib.h>
 #include <getopt.h>

Modified: trunk/libocfs2/expanddir.c
===================================================================
--- trunk/libocfs2/expanddir.c	2004-12-02 01:17:44 UTC (rev 445)
+++ trunk/libocfs2/expanddir.c	2004-12-02 01:42:12 UTC (rev 446)
@@ -30,6 +30,7 @@
 
 #include <stdio.h>
 #include <string.h>
+#include <inttypes.h>
 #if HAVE_UNISTD_H
 #include <unistd.h>
 #endif
@@ -40,7 +41,9 @@
  * ocfs2_expand_dir()
  *
  */
-errcode_t ocfs2_expand_dir(ocfs2_filesys *fs, uint64_t dir)
+errcode_t ocfs2_expand_dir(ocfs2_filesys *fs,
+			   uint64_t dir,
+			   uint64_t parent_dir)
 {
 	errcode_t ret = 0;
 	ocfs2_cached_inode *cinode = NULL;
@@ -94,8 +97,11 @@
 	if (ret) 
 		goto bail;
 
-	/* init new dir block */
-	ret = ocfs2_new_dir_block(fs, 0, 0, &buf);
+	/* init new dir block, with dotty entries if it's first */
+	if (used_blks == 0)
+		ret = ocfs2_new_dir_block(fs, dir, parent_dir, &buf);
+	else
+		ret = ocfs2_new_dir_block(fs, 0, 0, &buf);
 	if (ret)
 		goto bail;
 
@@ -104,6 +110,19 @@
 	if (ret)
 		goto bail;
 
+	/* did we just add a '..' reference to a parent?  if so, update
+	 * them */
+	if (used_blks == 0) {
+		ocfs2_dinode *parent = (ocfs2_dinode *)buf;
+		ret = ocfs2_read_inode(fs, parent_dir, buf);
+		if (ret)
+			goto bail;
+		parent->i_links_count++;
+		ret = ocfs2_write_inode(fs, parent_dir, buf);
+		if (ret)
+			goto bail;
+	}
+
 	/* increase the size */
 	inode->i_size += fs->fs_blocksize;
 
@@ -114,7 +133,7 @@
 
 bail:
 	if (buf)
-		ocfs2_free(buf);
+		ocfs2_free(&buf);
 
 	if (cinode)
 		ocfs2_free_cached_inode(fs, cinode);

Modified: trunk/libocfs2/extend_file.c
===================================================================
--- trunk/libocfs2/extend_file.c	2004-12-02 01:17:44 UTC (rev 445)
+++ trunk/libocfs2/extend_file.c	2004-12-02 01:42:12 UTC (rev 446)
@@ -300,29 +300,22 @@
 {
 	errcode_t ret = 0;
 	uint64_t n_clusters = 0;
-	uint64_t clustno;
+	uint64_t clustno, blkno;
 
-	/*
-	 * This should be, in essence:
-	 *
-	 * while (new_clusters) {
-	 * 	n_clusters = ocfs2_new_clusters();
-	 * 	ocfs2_insert_extent(n_clusters);
-	 * 	new_clusters -= n_clusters;
-	 * }
-	 */
-
 	if (!(fs->fs_flags & OCFS2_FLAG_RW))
 		return OCFS2_ET_RO_FILESYS;
 
 	while (new_clusters) {
-		/*n_clusters = ocfs2_new_clusters(); */
-
-		if (n_clusters == 0) {
-			ret = OCFS2_ET_NO_SPACE;
+		/* XXX lalala, for now we can only allocate precicely as
+		 * much as we ask for and we leak allocations.  leaking
+		 * allocations half-way through is a strong theme. */
+		n_clusters = 1;
+		ret = ocfs2_new_clusters(fs, n_clusters, &blkno);
+		if (ret)
 			goto bail;
-		}
 
+		clustno = ocfs2_blocks_to_clusters(fs, blkno);
+
 	 	ret = ocfs2_insert_extent(fs, ino, clustno, n_clusters);
 		if (ret)
 			goto bail;

Modified: trunk/libocfs2/include/bitmap.h
===================================================================
--- trunk/libocfs2/include/bitmap.h	2004-12-02 01:17:44 UTC (rev 445)
+++ trunk/libocfs2/include/bitmap.h	2004-12-02 01:42:12 UTC (rev 446)
@@ -65,6 +65,10 @@
 				  struct ocfs2_bitmap_region *br,
 				  uint64_t bitno,
 				  int new_val);
+	errcode_t (*alloc_range)(ocfs2_bitmap *bitmap, uint64_t len, 
+				 uint64_t *first_bit);
+	errcode_t (*clear_range)(ocfs2_bitmap *bitmap, uint64_t len, 
+				 uint64_t first_bit);
 };
 
 struct _ocfs2_bitmap {
@@ -111,6 +115,12 @@
 errcode_t ocfs2_bitmap_find_next_clear_generic(ocfs2_bitmap *bitmap,
 					       uint64_t start,
 					       uint64_t *found);
+errcode_t ocfs2_bitmap_alloc_range_generic(ocfs2_bitmap *bitmap,
+					   uint64_t len,
+					   uint64_t *first_bit);
+errcode_t ocfs2_bitmap_clear_range_generic(ocfs2_bitmap *bitmap,
+					   uint64_t len,
+					   uint64_t first_bit);
 errcode_t ocfs2_bitmap_set_holes(ocfs2_bitmap *bitmap,
 				 uint64_t bitno, int *oldval);
 errcode_t ocfs2_bitmap_clear_holes(ocfs2_bitmap *bitmap,

Modified: trunk/libocfs2/include/ocfs2.h
===================================================================
--- trunk/libocfs2/include/ocfs2.h	2004-12-02 01:17:44 UTC (rev 445)
+++ trunk/libocfs2/include/ocfs2.h	2004-12-02 01:42:12 UTC (rev 446)
@@ -407,6 +407,10 @@
 errcode_t ocfs2_bitmap_read(ocfs2_bitmap *bitmap);
 errcode_t ocfs2_bitmap_write(ocfs2_bitmap *bitmap);
 uint64_t ocfs2_bitmap_get_set_bits(ocfs2_bitmap *bitmap);
+errcode_t ocfs2_bitmap_alloc_range(ocfs2_bitmap *bitmap, uint64_t len, 
+				   uint64_t *first_bit);
+errcode_t ocfs2_bitmap_clear_range(ocfs2_bitmap *bitmap, uint64_t len, 
+				   uint64_t first_bit);
 
 errcode_t ocfs2_get_device_size(const char *file, int blocksize,
 				uint32_t *retblocks);
@@ -453,6 +457,14 @@
 errcode_t ocfs2_chain_free(ocfs2_filesys *fs,
 			   ocfs2_cached_inode *cinode,
 			   uint64_t bitno);
+errcode_t ocfs2_chain_alloc_range(ocfs2_filesys *fs,
+				  ocfs2_cached_inode *cinode,
+				  uint64_t requested,
+				  uint64_t *start_bit);
+errcode_t ocfs2_chain_free_range(ocfs2_filesys *fs,
+				 ocfs2_cached_inode *cinode,
+				 uint64_t len,
+				 uint64_t start_bit);
 errcode_t ocfs2_chain_test(ocfs2_filesys *fs,
 			   ocfs2_cached_inode *cinode,
 			   uint64_t bitno,
@@ -462,8 +474,12 @@
 				uint64_t blkno, 
 				int newval,
 				int *oldval);
+errcode_t ocfs2_chain_add_group(ocfs2_filesys *fs,
+				ocfs2_cached_inode *cinode);
 
-errcode_t ocfs2_expand_dir(ocfs2_filesys *fs, uint64_t dir);
+errcode_t ocfs2_expand_dir(ocfs2_filesys *fs,
+			   uint64_t dir,
+			   uint64_t parent_dir);
 
 errcode_t ocfs2_test_inode_allocated(ocfs2_filesys *fs, uint64_t blkno,
 				     int *is_allocated);
@@ -487,6 +503,12 @@
 errcode_t ocfs2_delete_extent_block(ocfs2_filesys *fs, uint64_t blkno);
 errcode_t ocfs2_extend_allocation(ocfs2_filesys *fs, uint64_t ino,
 				  uint64_t new_clusters);
+errcode_t ocfs2_new_clusters(ocfs2_filesys *fs,
+			     uint32_t requested,
+			     uint64_t *start_blkno);
+errcode_t ocfs2_free_clusters(ocfs2_filesys *fs,
+			      uint64_t len,
+			      uint64_t start_blkno);
 
 /* 
  * ${foo}_to_${bar} is a floor function.  blocks_to_clusters will

Modified: trunk/libocfs2/newdir.c
===================================================================
--- trunk/libocfs2/newdir.c	2004-12-02 01:17:44 UTC (rev 445)
+++ trunk/libocfs2/newdir.c	2004-12-02 01:42:12 UTC (rev 446)
@@ -42,10 +42,9 @@
 errcode_t ocfs2_new_dir_block(ocfs2_filesys *fs, uint64_t dir_ino,
 			      uint64_t parent_ino, char **block)
 {
-	struct ocfs2_dir_entry 	*dir = NULL;
+	struct ocfs2_dir_entry 	*dir;
 	errcode_t		ret;
 	char			*buf;
-	int			rec_len;
 
 	ret = ocfs2_malloc_block(fs->fs_io, &buf);
 	if (ret)
@@ -61,18 +60,19 @@
 		 * Set up entry for '.'
 		 */
 		dir->inode = dir_ino;
+		dir->rec_len = OCFS2_DIR_REC_LEN(1);
 		dir->name_len = 1;
+		dir->file_type = OCFS2_FT_DIR;
 		dir->name[0] = '.';
-		rec_len = dir->rec_len - OCFS2_DIR_REC_LEN(1);
-		dir->rec_len = OCFS2_DIR_REC_LEN(1);
 
 		/*
 		 * Set up entry for '..'
 		 */
 		dir = (struct ocfs2_dir_entry *) (buf + dir->rec_len);
-		dir->rec_len = rec_len;
 		dir->inode = parent_ino;
+		dir->rec_len = fs->fs_blocksize - OCFS2_DIR_REC_LEN(1);
 		dir->name_len = 2;
+		dir->file_type = OCFS2_FT_DIR;
 		dir->name[0] = '.';
 		dir->name[1] = '.';
 	}

Modified: trunk/libocfs2/ocfs2_err.et.in
===================================================================
--- trunk/libocfs2/ocfs2_err.et.in	2004-12-02 01:17:44 UTC (rev 445)
+++ trunk/libocfs2/ocfs2_err.et.in	2004-12-02 01:42:12 UTC (rev 446)
@@ -141,4 +141,7 @@
 ec	OCFS2_ET_NO_SPACE,
 	"No space available"
 
+ec	OCFS2_ET_ITERATION_COMPLETE,
+	"Iteration complete"
+
 	end

Modified: trunk/tunefs.ocfs2/tunefs.c
===================================================================
--- trunk/tunefs.ocfs2/tunefs.c	2004-12-02 01:17:44 UTC (rev 445)
+++ trunk/tunefs.ocfs2/tunefs.c	2004-12-02 01:42:12 UTC (rev 446)
@@ -287,7 +287,7 @@
 					 blkno, OCFS2_FT_REG_FILE);
 			if (ret) {
 				if (ret == OCFS2_ET_DIR_NO_SPACE) {
-					ret = ocfs2_expand_dir(fs, fs->fs_sysdir_blkno);
+					ret = ocfs2_expand_dir(fs, fs->fs_sysdir_blkno, fs->fs_sysdir_blkno);
 					if (!ret)
 						ret = ocfs2_link(fs, fs->fs_sysdir_blkno,
 								 fname, blkno, OCFS2_FT_REG_FILE);



More information about the Ocfs2-tools-commits mailing list