[Ocfs2-commits] mfasheh commits r1524 - branches/dlm-changes/src

svn-commits at oss.oracle.com svn-commits at oss.oracle.com
Wed Sep 29 20:01:11 CDT 2004


Author: mfasheh
Date: 2004-09-29 20:01:10 -0500 (Wed, 29 Sep 2004)
New Revision: 1524

Modified:
   branches/dlm-changes/src/aops.c
   branches/dlm-changes/src/file.c
   branches/dlm-changes/src/file.h
Log:
* tons of extend fixes.

* stop confusing new size with clusters to add in extend_file and
  extend_allocation

* print out the correct error code from ocfs_claim_bits and allocate_extent

* add some useful assertions

* correctly re-calculate clusters_to_add when we loop

* kill the overalloc code for now. we'll fill the stub with something better
  later.

* take the iatter junk out of extend_file -- it never belonged there and
  didn't work correctly anyway.

* switch around the args to extend_file to something more intuitive.

* properly update i_size at the bottom of extend file (we may not have
  everything we asked for yet).

* add some tracing



Modified: branches/dlm-changes/src/aops.c
===================================================================
--- branches/dlm-changes/src/aops.c	2004-09-30 00:59:27 UTC (rev 1523)
+++ branches/dlm-changes/src/aops.c	2004-09-30 01:01:10 UTC (rev 1524)
@@ -539,7 +539,7 @@
 	   blocks for the file. */
 	if (create && vbo_max > OCFS_I(inode)->ip_alloc_size) {
 		/* WARNING: How much do we really want to extend the file? */
-		status = ocfs_extend_file(osb, vbo_max, inode, NULL);
+		status = ocfs_extend_file(osb, inode, vbo_max);
 		if (status < 0) {
 			status = -ENOSPC;
 			LOG_ERROR_STR("ocfs_direct_IO_get_blocks: failed to extend the file!");

Modified: branches/dlm-changes/src/file.c
===================================================================
--- branches/dlm-changes/src/file.c	2004-09-30 00:59:27 UTC (rev 1523)
+++ branches/dlm-changes/src/file.c	2004-09-30 01:01:10 UTC (rev 1524)
@@ -57,6 +57,7 @@
 static int ocfs2_zero_extend(struct inode *inode);
 
 static unsigned int ocfs_calc_overalloc_bits(ocfs_super *osb, 
+					     struct file *filp,
 					     ocfs2_dinode *fe,
 					     u64 new_size);
 
@@ -645,7 +646,7 @@
 		LOG_TRACE_ARGS
 		    ("Writing at EOF, will need more allocation: have=%llu, "
 		     "need=%llu\n", OCFS_I(inode)->ip_alloc_size, newsize);
-		status = ocfs_extend_file(osb, newsize, inode, NULL);
+		status = ocfs_extend_file(osb, inode, newsize);
 		if (status < 0) {
 			if (status != -EINTR && status != -ENOSPC) {
 				LOG_ERROR_STATUS (status);
@@ -1006,7 +1007,7 @@
  */
 int ocfs_extend_allocation(ocfs_super *osb, 
 			   struct inode *inode, 
-			   u32 new_i_clusters, 
+			   u32 clusters_to_add, 
 			   struct buffer_head *fe_bh,
 			   ocfs_journal_handle *handle, 
 			   ocfs2_alloc_context *data_ac,
@@ -1016,11 +1017,10 @@
 	int status = 0;
 	int credits_needed, free_extents, multi_pass;
 	ocfs2_dinode *fe = (ocfs2_dinode *) fe_bh->b_data;
-	unsigned int bits_wanted;
 	u32 bit_off, num_bits;
 	u64 block;
 
-	OCFS_ASSERT(new_i_clusters > fe->i_clusters);
+	OCFS_ASSERT(clusters_to_add);
 
 	multi_pass = 0;
 again:
@@ -1052,16 +1052,14 @@
 		goto leave;
 	}
 
-	bits_wanted = new_i_clusters - fe->i_clusters;
-
 	/* do we have enough credits for another single extend, of
 	 * what's left? */
 	/* fe + main bitmap fe + main bitmap bits */
 	if (!multi_pass)
 		credits_needed = 1 + 1 + 
-			ocfs_blocks_for_bits(osb->sb, bits_wanted);
+			ocfs_blocks_for_bits(osb->sb, clusters_to_add);
 	else /* if we've already extended once, then we've already reserved. */
-		credits_needed = ocfs_blocks_for_bits(osb->sb, bits_wanted);
+		credits_needed = ocfs_blocks_for_bits(osb->sb, clusters_to_add);
 	if (!free_extents) {
 		/* will need to extend the file: 
 		 * metadata suballoc fe + metadata suballoc bitmap 
@@ -1082,10 +1080,12 @@
 
 	status = ocfs_claim_bits(osb, handle, data_ac, 1, &bit_off, &num_bits);
 	if (status < 0) {
-		LOG_ERROR_STATUS(free_extents);
+		LOG_ERROR_STATUS(status);
 		goto leave;
 	}
 
+	OCFS_ASSERT(num_bits <= clusters_to_add);
+
 	/* reserve our write early -- allocate_extent may update the inode */
 	status = ocfs_journal_access(handle, fe_bh, OCFS_JOURNAL_ACCESS_WRITE);
 	if (status < 0) {
@@ -1099,7 +1099,7 @@
 	status = ocfs_allocate_extent(osb, fe_bh, handle, block, num_bits, 
 				      inode, meta_ac);
 	if (status < 0) {
-		LOG_ERROR_STATUS(free_extents);
+		LOG_ERROR_STATUS(status);
 		goto leave;
 	}
 
@@ -1115,10 +1115,12 @@
 		goto leave;
 	}
 
-	if (fe->i_clusters < new_i_clusters) {
+	clusters_to_add -= num_bits;
+
+	if (clusters_to_add) {
 		LOG_TRACE_ARGS("need to alloc once more, clusters = %u, "
-			       "wanted = %u\n", 
-			       fe->i_clusters, new_i_clusters);
+			       "wanted = %u\n", fe->i_clusters, 
+			       clusters_to_add);
 		goto again;
 	}
 
@@ -1128,30 +1130,15 @@
 }
 
 static unsigned int ocfs_calc_overalloc_bits(ocfs_super *osb, 
+					     struct file *filp,
 					     ocfs2_dinode *fe,
 					     u64 new_size)
 {
-	u64 current_alloc = (u64)fe->i_clusters << osb->s_clustersize_bits;
-	int one_percentish_bits = 7;
-	u64 tmp_size, alloc_size = new_size - fe->i_size;
-
-	tmp_size = (current_alloc > ONE_MEGA_BYTE) ? ONE_MEGA_BYTE 
-		: current_alloc;
-
-	alloc_size += (tmp_size * 2);
-
-	if (alloc_size <
-	    (current_alloc >> one_percentish_bits)) {
-		alloc_size = current_alloc >> one_percentish_bits;
-		tmp_size = alloc_size;
-		// avoid using 64 bit mod
-		while (tmp_size > (10*ONE_MEGA_BYTE))
-			tmp_size -= (10*ONE_MEGA_BYTE);
-		tmp_size = (10*ONE_MEGA_BYTE) - tmp_size;
-		alloc_size += tmp_size;
-	}
-
-	return(ocfs_clusters_for_bytes(osb->sb, alloc_size) - fe->i_clusters);
+#warning "finish this"
+	/* TODO: We will keep a small history of allocs on the filp
+	 * and calculate a reasonable overalloc based on that data
+	 * here. */
+	return(0);
 }
 
 /* ocfs_extend_file()
@@ -1159,15 +1146,16 @@
  * Ok, this function is heavy on the goto's - we need to clean it up a
  * bit.
  */
-int ocfs_extend_file(ocfs_super *osb, u64 new_i_size,
-		     struct inode *inode, struct iattr *attr)
+int ocfs_extend_file(ocfs_super *osb, 
+		     struct inode *inode,
+		     u64 new_i_size)
 {
 	int status = 0;
 	int restart_func = 0;
 	int skip_overalloc = 0;
 	int credits, num_free_extents;
-	unsigned int overalloc_bits;
-	u32 new_i_clusters;
+	unsigned int overalloc_bits = 0;
+	u32 clusters_to_add;
 	struct buffer_head *bh = NULL;
 	ocfs2_dinode *fe;
 	ocfs_journal_handle *handle = NULL;
@@ -1177,6 +1165,7 @@
 
 	LOG_ENTRY_ARGS("(new_i_size=%llu)\n", new_i_size);
 
+	/* setattr sometimes calls us like this. */
 	if (new_i_size == 0)
 		goto leave;
 
@@ -1204,20 +1193,32 @@
 	OCFS_ASSERT(IS_VALID_FILE_ENTRY(fe));
 	OCFS_ASSERT(new_i_size >= fe->i_size);
 
-	new_i_clusters = ocfs_clusters_for_bytes(osb->sb, new_i_size);
+	if (fe->i_size == new_i_size) {
+		OCFS_ASSERT(inode->i_size == new_i_size);
+		goto leave;
+	}
 
-	if (new_i_size <= (fe->i_clusters << osb->s_clustersize_bits))
+	clusters_to_add = ocfs_clusters_for_bytes(osb->sb, new_i_size) 
+		- fe->i_clusters;
+
+	LOG_TRACE_ARGS("extend inode %llu, new_i_size = %llu, i_size = %llu, "
+		       "fe->i_clusters = %u, clusters_to_add = %u\n", 
+		       OCFS_I(inode)->ip_blkno, new_i_size, inode->i_size, 
+		       fe->i_clusters, clusters_to_add);
+
+	if (!clusters_to_add) 
 		goto do_start_trans;
 
+	overalloc_bits = 0;
 	if (!skip_overalloc) {
-		overalloc_bits = ocfs_calc_overalloc_bits(osb, fe, new_i_size);
-		new_i_clusters += overalloc_bits;
+		overalloc_bits = ocfs_calc_overalloc_bits(osb, 
+							  NULL, 
+							  fe, 
+							  new_i_size);
+		clusters_to_add += overalloc_bits;
 		skip_overalloc = 1;
 	}
 
-	LOG_TRACE_ARGS("i_clusters=%u, wanted==%u\n",
-		       fe->i_clusters, new_i_clusters);
-
 	num_free_extents = ocfs_num_free_extents(osb, 
 						 inode, 
 						 fe);
@@ -1226,6 +1227,7 @@
 		LOG_ERROR_STATUS(status);
 		goto leave;
 	}
+
 	if (!num_free_extents) {
 		status = ocfs_reserve_new_metadata(osb, 
 						   handle, 
@@ -1237,14 +1239,18 @@
 		}
 	}
 
-	status = ocfs_reserve_bits(osb, handle, new_i_clusters, &data_ac);
+	status = ocfs_reserve_bits(osb, 
+				   handle, 
+				   clusters_to_add,
+				   &data_ac);
 	if (status < 0) {
-		LOG_ERROR_STATUS(status);
+		if (status != -ENOSPC)
+			LOG_ERROR_STATUS(status);
 		goto leave;
 	}
 
 do_start_trans:
-	credits = ocfs_calc_extend_credits(osb->sb, new_i_clusters);
+	credits = ocfs_calc_extend_credits(osb->sb, clusters_to_add);
 	handle = ocfs_start_trans(osb, handle, credits);
 	if (handle == NULL) {
 		LOG_ERROR_STATUS(status = -ENOMEM);
@@ -1261,12 +1267,12 @@
 		goto leave;
 	}
 
-	if (new_i_size <= (fe->i_clusters << osb->s_clustersize_bits))
+	if (!clusters_to_add)
 		goto no_alloc;
 
 	status = ocfs_extend_allocation(osb, 
 					inode, 
-					new_i_clusters - fe->i_clusters,
+					clusters_to_add,
 					bh,
 					handle,
 					data_ac,
@@ -1280,9 +1286,9 @@
 	if (status == -EAGAIN 
 	    && (new_i_size > 
 		(fe->i_clusters << osb->s_clustersize_bits))) {
-		new_i_clusters -= fe->i_clusters;
 
 		if (why == RESTART_META) {
+			LOG_TRACE_ARGS("restarting function.\n");
 			restart_func = 1;
 		} else {
 			OCFS_ASSERT(why == RESTART_TRANS);
@@ -1298,9 +1304,13 @@
 				goto leave;
 			}
 
+			clusters_to_add = 
+				ocfs_clusters_for_bytes(osb->sb, new_i_size)
+				- fe->i_clusters + overalloc_bits;
+			LOG_TRACE_ARGS("restarting transaction.\n");
 			/* TODO: This can be more intelligent. */
 			credits = ocfs_calc_extend_credits(osb->sb, 
-							   new_i_clusters);
+							   clusters_to_add);
 			status = ocfs_extend_trans(handle, credits);
 			if (status < 0) {
 				/* handle still has to be committed /
@@ -1314,8 +1324,12 @@
 	status = 0;
 
 no_alloc:
-	/* Update the file size and add the new one to old one. */
-	fe->i_size = new_i_size;
+	/* this may not be the end of our allocation so only update
+	 * i_size to what's appropriate. */
+	if (new_i_size > (fe->i_clusters << osb->s_clustersize_bits))
+		fe->i_size = fe->i_clusters << osb->s_clustersize_bits;
+	else
+		fe->i_size = new_i_size;
 #warning "is there a reason why we don't update i_blocks here?"
 	LOG_TRACE_ARGS("fe: i_clusters = %u, i_size=%llu\n", 
 		       fe->i_clusters, fe->i_size);
@@ -1323,10 +1337,6 @@
 	LOG_TRACE_ARGS("inode: ip_alloc_size=%llu, i_size=%llu\n",
 		       OCFS_I(inode)->ip_alloc_size, inode->i_size);
 
-	if (attr) {
-		ocfs_fe_set_attributes(fe, attr);
-		attr = NULL;
-	}
 	fe->i_mtime = OCFS_CURRENT_TIME;
 
 	status = ocfs_journal_dirty(handle, bh);
@@ -1375,7 +1385,6 @@
 	int status;
 	ocfs_super *osb = NULL;
 	struct super_block *sb = inode->i_sb;
-	int extended = 0;
 
 	LOG_SET_CONTEXT(SETATTR);
 
@@ -1438,11 +1447,9 @@
 			ocfs_truncate_inode_pages(inode, newsize);
 			status = ocfs_truncate_file(osb, newsize, 
 						    inode);
+		} else {
+			status = ocfs_extend_file(osb, inode, newsize);
 		}
-		else {
-			status = ocfs_extend_file(osb, newsize, inode, attr);
-			extended = 1;
-		}
 		if (status < 0) {
 			if (status != -EINTR)
 				LOG_ERROR_STATUS (status);
@@ -1467,14 +1474,12 @@
 	}
 
 	status = -EFAIL;
-	if (!extended) {
-		status = ocfs_change_file_attrib(osb, attr, inode);
-		if (status < 0) {
-			if (status != -EINTR)
-				LOG_ERROR_STATUS (status);
-			error = -EIO;
-			goto bail;
-		}
+	status = ocfs_change_file_attrib(osb, attr, inode);
+	if (status < 0) {
+		if (status != -EINTR)
+			LOG_ERROR_STATUS (status);
+		error = -EIO;
+		goto bail;
 	}
 	error = inode_setattr (inode, attr);
 

Modified: branches/dlm-changes/src/file.h
===================================================================
--- branches/dlm-changes/src/file.h	2004-09-30 00:59:27 UTC (rev 1523)
+++ branches/dlm-changes/src/file.h	2004-09-30 01:01:10 UTC (rev 1524)
@@ -39,16 +39,15 @@
 };
 int ocfs_extend_allocation(ocfs_super *osb, 
 			   struct inode *inode, 
-			   u32 new_i_clusters, 
+			   u32 clusters_to_add, 
 			   struct buffer_head *fe_bh,
 			   ocfs_journal_handle *handle, 
 			   ocfs2_alloc_context *data_ac,
 			   ocfs2_alloc_context *meta_ac,
 			   enum ocfs2_alloc_restarted *reason);
 int ocfs_extend_file(ocfs_super *osb, 
-		     u64 new_i_size,
-		     struct inode *inode, 
-		     struct iattr *attr);
+		     struct inode *inode,
+		     u64 new_i_size);
 int ocfs_inode_fill_ext_map(ocfs_super *osb, struct buffer_head *fe_bh,
 			    struct inode *inode);
 int ocfs_setattr(struct dentry *dentry, struct iattr *attr);



More information about the Ocfs2-commits mailing list