[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