[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