[Ocfs2-tools-devel] [PATCH 2/6] libocfs2: extend xattr and xattr value tree
Tiger Yang
tiger.yang at oracle.com
Wed Jul 29 00:01:29 PDT 2009
Add ocfs2_tree_extend_allocation and ocfs2_tree_insert_extent
for extending xattr record and xattr value tree.
On the other hand, use ocfs2_extend_allocation and
ocfs2_inode_insert_extent extend file data tree.
Signed-off-by: Tiger Yang <tiger.yang at oracle.com>
---
fswreck/extent.c | 4 +-
include/ocfs2/ocfs2.h | 9 +-
libocfs2/extend_file.c | 396 +++++++++++++++++++++++------------
libocfs2/xattr.c | 3 +-
tunefs.ocfs2/feature_sparse_files.c | 2 +-
5 files changed, 276 insertions(+), 138 deletions(-)
diff --git a/fswreck/extent.c b/fswreck/extent.c
index e3fe020..2970cd9 100644
--- a/fswreck/extent.c
+++ b/fswreck/extent.c
@@ -103,8 +103,8 @@ static void custom_extend_allocation(ocfs2_filesys *fs, uint64_t ino,
* we insert each cluster in reverse. */
for(i = n_clusters; i; --i) {
tmpblk = blkno + ocfs2_clusters_to_blocks(fs, i - 1);
- ret = ocfs2_insert_extent(fs, ino, offset++,
- tmpblk, 1, 0);
+ ret = ocfs2_inode_insert_extent(fs, ino, offset++,
+ tmpblk, 1, 0);
if (ret)
FSWRK_COM_FATAL(progname, ret);
}
diff --git a/include/ocfs2/ocfs2.h b/include/ocfs2/ocfs2.h
index 3c4195c..a171089 100644
--- a/include/ocfs2/ocfs2.h
+++ b/include/ocfs2/ocfs2.h
@@ -507,9 +507,9 @@ void ocfs2_init_group_desc(ocfs2_filesys *fs,
errcode_t ocfs2_new_dir_block(ocfs2_filesys *fs, uint64_t dir_ino,
uint64_t parent_ino, char **block);
-errcode_t ocfs2_insert_extent(ocfs2_filesys *fs, uint64_t ino, uint32_t cpos,
- uint64_t c_blkno, uint32_t clusters,
- uint16_t flag);
+errcode_t ocfs2_inode_insert_extent(ocfs2_filesys *fs, uint64_t ino,
+ uint32_t cpos, uint64_t c_blkno,
+ uint32_t clusters, uint16_t flag);
errcode_t ocfs2_cached_inode_insert_extent(ocfs2_cached_inode *ci,
uint32_t cpos, uint64_t c_blkno,
uint32_t clusters, uint16_t flag);
@@ -1117,7 +1117,8 @@ errcode_t ocfs2_block_iterate_inode(ocfs2_filesys *fs,
uint32_t ocfs2_xattr_uuid_hash(unsigned char *uuid);
uint32_t ocfs2_xattr_name_hash(uint32_t uuid_hash, const char *name,
int name_len);
-int ocfs2_xattr_find_leaf(ocfs2_filesys *fs, struct ocfs2_xattr_block *xb,
+int ocfs2_xattr_find_leaf(ocfs2_filesys *fs, struct ocfs2_extent_list *el,
+ uint64_t el_blkno, char *el_blk,
uint32_t cpos, char **leaf_buf);
uint16_t ocfs2_xattr_buckets_per_cluster(ocfs2_filesys *fs);
uint16_t ocfs2_blocks_per_xattr_bucket(ocfs2_filesys *fs);
diff --git a/libocfs2/extend_file.c b/libocfs2/extend_file.c
index a27b478..671f807 100644
--- a/libocfs2/extend_file.c
+++ b/libocfs2/extend_file.c
@@ -34,6 +34,8 @@
#include <errno.h>
#include <assert.h>
#include "ocfs2/ocfs2.h"
+#include "xattr.h"
+#include "extent_tree.h"
/*
* Structures which describe a path through a btree, and functions to
@@ -452,7 +454,7 @@ static inline uint32_t ocfs2_sum_rightmost_rec(struct ocfs2_extent_list *el)
* contain a single record with e_clusters == 0.
*/
static int ocfs2_add_branch(ocfs2_filesys *fs,
- struct ocfs2_dinode *fe,
+ struct ocfs2_extent_tree *et,
char *eb_buf,
char **last_eb_buf)
{
@@ -473,7 +475,7 @@ static int ocfs2_add_branch(ocfs2_filesys *fs,
eb = (struct ocfs2_extent_block *) eb_buf;
el = &eb->h_list;
} else
- el = &fe->id2.i_list;
+ el = et->et_root_el;
/* we never add a branch to a leaf. */
assert(el->l_tree_depth);
@@ -560,7 +562,7 @@ static int ocfs2_add_branch(ocfs2_filesys *fs,
/* fe needs a new last extent block pointer, as does the
* next_leaf on the previously last-extent-block.
*/
- fe->i_last_eb_blk = new_last_eb_blk;
+ et->et_ops->eo_set_last_eb_blk(et, new_last_eb_blk);
/* here all the extent block and the new inode information should be
* written back to the disk.
@@ -635,20 +637,17 @@ bail:
* return status < 0 indicates an error.
*/
static errcode_t ocfs2_find_branch_target(ocfs2_filesys *fs,
- struct ocfs2_dinode *fe,
+ struct ocfs2_extent_list *el,
char **target_buf)
{
errcode_t ret = 0;
int i;
uint64_t blkno;
struct ocfs2_extent_block *eb;
- struct ocfs2_extent_list *el;
char *buf = NULL, *lowest_buf = NULL;
*target_buf = NULL;
- el = &fe->id2.i_list;
-
ret = ocfs2_malloc_block(fs->fs_io, &buf);
if (ret)
return ret;
@@ -678,8 +677,7 @@ static errcode_t ocfs2_find_branch_target(ocfs2_filesys *fs,
/* If we didn't find one and the fe doesn't have any room,
* then return '1' */
- if (!lowest_buf
- && (fe->id2.i_list.l_next_free_rec == fe->id2.i_list.l_count))
+ if (!lowest_buf && el->l_next_free_rec == el->l_count)
ret = 1;
*target_buf = lowest_buf;
@@ -1027,27 +1025,37 @@ out:
return ret;
}
-int ocfs2_xattr_find_leaf(ocfs2_filesys *fs, struct ocfs2_xattr_block *xb,
+static struct ocfs2_path *ocfs2_new_tree_path(struct ocfs2_extent_list *el,
+ uint64_t el_blkno, char *el_blk)
+{
+ struct ocfs2_path *path = NULL;
+
+ if (ocfs2_malloc0(sizeof(*path), &path))
+ return NULL;
+
+ path->p_tree_depth = el->l_tree_depth;
+ path->p_node[0].blkno = el_blkno;
+ path->p_node[0].buf = el_blk;
+ path->p_node[0].el = el;
+
+ return path;
+}
+
+int ocfs2_xattr_find_leaf(ocfs2_filesys *fs, struct ocfs2_extent_list *el,
+ uint64_t el_blkno, char *el_blk,
uint32_t cpos, char **leaf_buf)
{
int ret;
char *buf = NULL;
struct ocfs2_path *path = NULL;
- struct ocfs2_extent_list *el = &xb->xb_attrs.xb_root.xt_list;
assert(el->l_tree_depth > 0);
-
- ret = ocfs2_malloc0(sizeof(*path), &path);
+ path = ocfs2_new_tree_path(el, el_blkno, el_blk);
if (!path) {
ret = OCFS2_ET_NO_MEMORY;
goto out;
- } else {
- path->p_tree_depth = el->l_tree_depth;
- path->p_node[0].blkno = xb->xb_blkno;
- path->p_node[0].buf = (char *)xb;
- path->p_node[0].el = el;
}
ret = ocfs2_find_path(fs, path, cpos);
@@ -2411,17 +2419,16 @@ static void ocfs2_subtract_from_rec(ocfs2_filesys *fs,
* and then pointing the dinode to the new extent_block.
*/
static errcode_t shift_tree_depth(ocfs2_filesys *fs,
- struct ocfs2_dinode *di,
+ struct ocfs2_extent_tree *et,
char **new_eb)
{
errcode_t ret;
char *buf = NULL;
uint64_t blkno;
+ struct ocfs2_extent_list *el = et->et_root_el;
struct ocfs2_extent_block *eb;
- struct ocfs2_extent_list *el;
uint32_t new_clusters;
- el = &di->id2.i_list;
if (el->l_next_free_rec != el->l_count)
return OCFS2_ET_INTERNAL_FAILURE;
@@ -2454,7 +2461,7 @@ static errcode_t shift_tree_depth(ocfs2_filesys *fs,
el->l_next_free_rec = 1;
if (el->l_tree_depth == 1)
- di->i_last_eb_blk = blkno;
+ et->et_ops->eo_set_last_eb_blk(et, blkno);
ret = ocfs2_write_extent_block(fs, blkno, buf);
if (!ret)
@@ -2574,68 +2581,21 @@ set_tail_append:
* This computes a few things that are commonly used in the process of
* inserting into the btree:
* - Whether the new extent is contiguous with an existing one.
- * - The current tree depth.
* - Whether the insert is an appending one.
- * - The total # of free records in the tree.
*
* All of the information is stored on the ocfs2_insert_type
* structure.
*/
static int ocfs2_figure_insert_type(struct insert_ctxt *ctxt,
- char **last_eb_buf,
- int *free_records,
+ struct ocfs2_path *path,
+ uint64_t last_eb_blk,
struct ocfs2_insert_type *insert)
{
int ret;
- struct ocfs2_extent_block *eb;
- struct ocfs2_extent_list *el;
- struct ocfs2_dinode *di = ctxt->di;
struct ocfs2_extent_rec *insert_rec = &ctxt->rec;
ocfs2_filesys *fs = ctxt->fs;
- struct ocfs2_path *path = NULL;
- char *buf = *last_eb_buf;
-
- insert->ins_split = SPLIT_NONE;
-
- el = &di->id2.i_list;
- insert->ins_tree_depth = el->l_tree_depth;
-
- if (el->l_tree_depth) {
- /*
- * If we have tree depth, we read in the
- * rightmost extent block ahead of time as
- * ocfs2_figure_insert_type() and ocfs2_add_branch()
- * may want it later.
- */
- assert(buf);
- ret = ocfs2_read_extent_block(fs, di->i_last_eb_blk, buf);
- if (ret)
- goto out;
-
- eb = (struct ocfs2_extent_block *) buf;
- el = &eb->h_list;
- }
- /*
- * Unless we have a contiguous insert, we'll need to know if
- * there is room left in our allocation tree for another
- * extent record.
- *
- * XXX: This test is simplistic, we can search for empty
- * extent records too.
- */
- *free_records = el->l_count - el->l_next_free_rec;
-
- if (!insert->ins_tree_depth) {
- ocfs2_figure_contig_type(fs, insert, el, insert_rec);
- ocfs2_figure_appending_type(insert, el, insert_rec);
- return 0;
- }
+ struct ocfs2_extent_list *el = NULL;
- path = ocfs2_new_inode_path(fs, di);
- if (!path) {
- ret = OCFS2_ET_NO_MEMORY;
- goto out;
- }
/*
* In the case that we're inserting past what the tree
* currently accounts for, ocf2_find_path() will return for
@@ -2644,7 +2604,7 @@ static int ocfs2_figure_insert_type(struct insert_ctxt *ctxt,
*/
ret = ocfs2_find_path(fs, path, insert_rec->e_cpos);
if (ret)
- goto out;
+ return ret;
el = path_leaf_el(path);
@@ -2677,7 +2637,7 @@ static int ocfs2_figure_insert_type(struct insert_ctxt *ctxt,
* the case that we're doing a tail append, so maybe we can
* take advantage of that information somehow.
*/
- if (di->i_last_eb_blk == path_leaf_blkno(path)) {
+ if (last_eb_blk == path_leaf_blkno(path)) {
/*
* Ok, ocfs2_find_path() returned us the rightmost
* tree path. This might be an appending insert. There are
@@ -2689,9 +2649,6 @@ static int ocfs2_figure_insert_type(struct insert_ctxt *ctxt,
ocfs2_figure_appending_type(insert, el, insert_rec);
}
-out:
- ocfs2_free_path(path);
-
return ret;
}
@@ -2990,28 +2947,17 @@ out:
return ret;
}
-static int ocfs2_do_insert_extent(struct insert_ctxt* ctxt,
- struct ocfs2_insert_type *type)
+static int __ocfs2_do_insert_extent(struct insert_ctxt *ctxt,
+ struct ocfs2_insert_type *type,
+ struct ocfs2_extent_list *el,
+ struct ocfs2_path *right_path)
{
- int ret, rotate = 0;
+ int ret = 0;
+ int rotate = 0;
uint32_t cpos;
- struct ocfs2_path *right_path = NULL;
struct ocfs2_path *left_path = NULL;
struct ocfs2_extent_rec *insert_rec = &ctxt->rec;
ocfs2_filesys *fs = ctxt->fs;
- struct ocfs2_dinode *di = ctxt->di;
- struct ocfs2_extent_list *el = &di->id2.i_list;
-
- if (el->l_tree_depth == 0) {
- ocfs2_insert_at_leaf(fs, insert_rec, el, type);
- goto out_update_clusters;
- }
-
- right_path = ocfs2_new_inode_path(fs, di);
- if (!right_path) {
- ret = OCFS2_ET_NO_MEMORY;
- goto out;
- }
/*
* Determine the path to start with. Rotations need the
@@ -3027,7 +2973,7 @@ static int ocfs2_do_insert_extent(struct insert_ctxt* ctxt,
ret = ocfs2_find_path(fs, right_path, cpos);
if (ret)
- goto out;
+ return ret;
/*
* Rotations and appends need special treatment - they modify
@@ -3042,33 +2988,52 @@ static int ocfs2_do_insert_extent(struct insert_ctxt* ctxt,
* can wind up skipping both of these two special cases...
*/
- if (rotate) {
+ if (rotate)
ret = ocfs2_rotate_tree_right(fs, type->ins_split,
insert_rec->e_cpos,
right_path, &left_path);
- if (ret)
- goto out;
- } else if (type->ins_appending == APPEND_TAIL
- && type->ins_contig != CONTIG_LEFT) {
+ else if (type->ins_appending == APPEND_TAIL
+ && type->ins_contig != CONTIG_LEFT)
ret = ocfs2_append_rec_to_path(fs, insert_rec,
right_path, &left_path);
- if (ret)
- goto out;
- }
+ if (ret)
+ return ret;
ret = ocfs2_insert_path(ctxt, left_path, right_path, insert_rec, type);
+
+ ocfs2_free_path(left_path);
+
+ return ret;
+}
+
+static int ocfs2_inode_do_insert_extent(struct insert_ctxt *ctxt,
+ struct ocfs2_insert_type *type)
+{
+ int ret = 0;
+ struct ocfs2_path *right_path = NULL;
+ struct ocfs2_extent_rec *insert_rec = &ctxt->rec;
+ ocfs2_filesys *fs = ctxt->fs;
+ struct ocfs2_dinode *di = ctxt->di;
+ struct ocfs2_extent_list *el = &di->id2.i_list;
+
+ if (el->l_tree_depth == 0) {
+ ocfs2_insert_at_leaf(fs, insert_rec, el, type);
+ goto out_update_clusters;
+ }
+
+ right_path = ocfs2_new_inode_path(fs, di);
+ if (!right_path)
+ return OCFS2_ET_NO_MEMORY;
+
+ ret = __ocfs2_do_insert_extent(ctxt, type, el, right_path);
if (ret)
goto out;
out_update_clusters:
if (type->ins_split == SPLIT_NONE)
di->i_clusters += insert_rec->e_leaf_clusters;
- ret = 0;
-
out:
- ocfs2_free_path(left_path);
ocfs2_free_path(right_path);
-
return ret;
}
@@ -3289,15 +3254,17 @@ static void free_duplicated_extent_block_dinode(ocfs2_filesys *fs,
*
* *last_eb will be updated by ocfs2_add_branch().
*/
-static int ocfs2_grow_tree(ocfs2_filesys *fs, struct ocfs2_dinode *di,
+static int ocfs2_grow_tree(ocfs2_filesys *fs,
+ struct ocfs2_extent_tree *et,
int *final_depth, char **last_eb)
{
errcode_t ret;
char *eb_buf = NULL;
int shift;
- int depth = di->id2.i_list.l_tree_depth;
+ struct ocfs2_extent_list *el = et->et_root_el;
+ int depth = el->l_tree_depth;
- shift = ocfs2_find_branch_target(fs, di, &eb_buf);
+ shift = ocfs2_find_branch_target(fs, el, &eb_buf);
if (shift < 0) {
ret = shift;
goto out;
@@ -3311,7 +3278,7 @@ static int ocfs2_grow_tree(ocfs2_filesys *fs, struct ocfs2_dinode *di,
/* shift_tree_depth will return us a buffer with
* the new extent block (so we can pass that to
* ocfs2_add_branch). */
- ret = shift_tree_depth(fs, di, &eb_buf);
+ ret = shift_tree_depth(fs, et, &eb_buf);
if (ret)
goto out;
@@ -3332,7 +3299,7 @@ static int ocfs2_grow_tree(ocfs2_filesys *fs, struct ocfs2_dinode *di,
/* call ocfs2_add_branch to add the final part of the tree with
* the new data. */
- ret = ocfs2_add_branch(fs, di, eb_buf, last_eb);
+ ret = ocfs2_add_branch(fs, et, eb_buf, last_eb);
out:
if (final_depth)
@@ -3343,9 +3310,9 @@ out:
/*
* Insert an extent into an inode btree.
*/
-errcode_t ocfs2_insert_extent(ocfs2_filesys *fs, uint64_t ino, uint32_t cpos,
- uint64_t c_blkno, uint32_t clusters,
- uint16_t flag)
+errcode_t ocfs2_inode_insert_extent(ocfs2_filesys *fs, uint64_t ino,
+ uint32_t cpos, uint64_t c_blkno,
+ uint32_t clusters, uint16_t flag)
{
errcode_t ret;
ocfs2_cached_inode *ci = NULL;
@@ -3378,8 +3345,9 @@ errcode_t ocfs2_cached_inode_insert_extent(ocfs2_cached_inode *ci,
char *last_eb = NULL;
char *backup_buf = NULL;
char *di_buf = NULL;
- int free_records = 0;
ocfs2_filesys *fs = ci->ci_fs;
+ struct ocfs2_extent_list *el = &ci->ci_inode->id2.i_list;
+ struct ocfs2_path *path = NULL;
ctxt.fs = fs;
ctxt.di = ci->ci_inode;
@@ -3393,7 +3361,7 @@ errcode_t ocfs2_cached_inode_insert_extent(ocfs2_cached_inode *ci,
* And if the duplicate process fails, we should go on the normal
* insert process.
*/
- if (ctxt.di->id2.i_list.l_tree_depth) {
+ if (el->l_tree_depth) {
ret = ocfs2_malloc_block(fs->fs_io, &backup_buf);
if (ret)
goto bail;
@@ -3422,22 +3390,53 @@ errcode_t ocfs2_cached_inode_insert_extent(ocfs2_cached_inode *ci,
if (ret)
return ret;
- ret = ocfs2_figure_insert_type(&ctxt, &last_eb, &free_records, &insert);
- if (ret)
- goto bail;
+ insert.ins_split = SPLIT_NONE;
+ insert.ins_tree_depth = el->l_tree_depth;
- if (insert.ins_contig == CONTIG_NONE && free_records == 0) {
- ret = ocfs2_grow_tree(fs, ctxt.di,
- &insert.ins_tree_depth, &last_eb);
+ if (!el->l_tree_depth) {
+ ocfs2_figure_contig_type(fs, &insert, el , &ctxt.rec);
+ ocfs2_figure_appending_type(&insert, el, &ctxt.rec);
+ } else {
+ /*
+ * If we have tree depth, we read in the
+ * rightmost extent block ahead of time as
+ * ocfs2_figure_insert_type() and ocfs2_add_branch()
+ * may want it later.
+ */
+ ret = ocfs2_read_extent_block(fs, ctxt.di->i_last_eb_blk,
+ last_eb);
if (ret)
goto bail;
+ el = &((struct ocfs2_extent_block *)last_eb)->h_list;
+
+ path = ocfs2_new_inode_path(fs, ctxt.di);
+ if (!path) {
+ ret = OCFS2_ET_NO_MEMORY;
+ goto bail;
+ }
+ ret = ocfs2_figure_insert_type(&ctxt, path,
+ ctxt.di->i_last_eb_blk,
+ &insert);
+ if (ret)
+ goto free_path;
+ }
+
+ if (insert.ins_contig == CONTIG_NONE &&
+ el->l_count == el->l_next_free_rec) {
+ struct ocfs2_extent_tree et;
+
+ ocfs2_init_dinode_extent_tree(&et, fs, (char *)ci->ci_inode);
+ ret = ocfs2_grow_tree(fs, &et,
+ &insert.ins_tree_depth, &last_eb);
+ if (ret)
+ goto free_path;
}
/* Finally, we can add clusters. This might rotate the tree for us. */
- ret = ocfs2_do_insert_extent(&ctxt, &insert);
- if (ret)
- goto bail;
+ ret = ocfs2_inode_do_insert_extent(&ctxt, &insert);
+free_path:
+ ocfs2_free_path(path);
bail:
if (backup_buf) {
/* we have duplicated the extent block during the insertion.
@@ -3507,7 +3506,11 @@ leftright:
}
if (rightmost_el->l_next_free_rec == rightmost_el->l_count) {
- ret = ocfs2_grow_tree(ctxt->fs, ctxt->di, &depth, last_eb_buf);
+ struct ocfs2_extent_tree et;
+
+ ocfs2_init_dinode_extent_tree(&et, ctxt->fs, (char *)ctxt->di);
+ ret = ocfs2_grow_tree(ctxt->fs, &et,
+ &depth, last_eb_buf);
if (ret)
goto out;
}
@@ -3540,7 +3543,7 @@ leftright:
do_leftright = 1;
}
- ret = ocfs2_do_insert_extent(ctxt, &insert);
+ ret = ocfs2_inode_do_insert_extent(ctxt, &insert);
if (ret)
goto out;
@@ -3764,6 +3767,139 @@ out:
return ret;
}
+errcode_t ocfs2_tree_insert_extent(ocfs2_cached_inode *ci,
+ uint32_t cpos, uint64_t c_blkno,
+ uint32_t clusters, uint16_t flag,
+ struct ocfs2_extent_tree *et)
+{
+ errcode_t ret = 0;
+ struct insert_ctxt ctxt;
+ struct ocfs2_insert_type insert = {0, };
+ char *last_eb = NULL;
+ char *di_buf = NULL;
+ ocfs2_filesys *fs = ci->ci_fs;
+ struct ocfs2_extent_list *el = et->et_root_el;
+ struct ocfs2_path *path = NULL;
+
+ ctxt.fs = fs;
+ ctxt.di = ci->ci_inode;
+ di_buf = (char *)ctxt.di;
+
+ memset(&ctxt.rec, 0, sizeof(struct ocfs2_extent_rec));
+ ctxt.rec.e_cpos = cpos;
+ ctxt.rec.e_blkno = c_blkno;
+ ctxt.rec.e_leaf_clusters = clusters;
+ ctxt.rec.e_flags = flag;
+
+ insert.ins_split = SPLIT_NONE;
+ insert.ins_tree_depth = el->l_tree_depth;
+
+ if (!el->l_tree_depth) {
+ ocfs2_figure_contig_type(fs, &insert, el , &ctxt.rec);
+ ocfs2_figure_appending_type(&insert, el, &ctxt.rec);
+ } else {
+ /*
+ * If we have tree depth, we read in the
+ * rightmost extent block ahead of time as
+ * ocfs2_figure_insert_type() and ocfs2_add_branch()
+ * may want it later.
+ */
+ uint64_t last_eb_blk = et->et_ops->eo_get_last_eb_blk(et);
+
+ ret = ocfs2_malloc_block(fs->fs_io, &last_eb);
+ if (ret)
+ return ret;
+ ret = ocfs2_read_extent_block(fs, last_eb_blk, last_eb);
+ if (ret)
+ goto bail;
+ el = &((struct ocfs2_extent_block *)last_eb)->h_list;
+
+ path = ocfs2_new_tree_path(el, last_eb_blk, last_eb);
+ if (!path) {
+ ret = OCFS2_ET_NO_MEMORY;
+ goto bail;
+ }
+ ret = ocfs2_figure_insert_type(&ctxt, path, last_eb_blk,
+ &insert);
+ if (ret)
+ goto free_path;
+ }
+
+ if (insert.ins_contig == CONTIG_NONE &&
+ el->l_count == el->l_next_free_rec) {
+ ret = ocfs2_grow_tree(fs, et, &insert.ins_tree_depth,
+ &last_eb);
+ if (ret)
+ goto free_path;
+ }
+
+ if (el->l_tree_depth == 0) {
+ ocfs2_insert_at_leaf(fs, &ctxt.rec, el, &insert);
+ goto out_update_clusters;
+ }
+
+ /* Finally, we can add clusters. This might rotate the tree for us. */
+ ret = __ocfs2_do_insert_extent(&ctxt, &insert, el, path);
+ if (ret)
+ goto free_path;
+
+out_update_clusters:
+ if (insert.ins_split == SPLIT_NONE)
+ et->et_ops->eo_update_clusters(et, ctxt.rec.e_leaf_clusters);
+ ret = 0;
+
+free_path:
+ ocfs2_free_path(path);
+bail:
+
+ if (last_eb)
+ ocfs2_free(&last_eb);
+
+ return ret;
+}
+
+errcode_t ocfs2_tree_extend_allocation(ocfs2_cached_inode *ci,
+ uint32_t new_clusters,
+ struct ocfs2_extent_tree *et)
+{
+ ocfs2_filesys *fs = ci->ci_fs;
+ errcode_t ret = 0;
+ uint32_t n_clusters = 0, cpos;
+ uint64_t blkno;
+ char *buf = NULL;
+
+ if (!(fs->fs_flags & OCFS2_FLAG_RW))
+ return OCFS2_ET_RO_FILESYS;
+
+ cpos = et->et_ops->eo_get_clusters(et);
+ while (new_clusters) {
+ n_clusters = 1;
+ ret = ocfs2_new_clusters(fs, 1, new_clusters, &blkno,
+ &n_clusters);
+ if (ret)
+ break;
+
+ ret = ocfs2_tree_insert_extent(ci, cpos, blkno,
+ n_clusters, 0, et);
+ if (ret) {
+ /* XXX: We don't wan't to overwrite the error
+ * from insert_extent(). But we probably need
+ * to BE LOUDLY UPSET. */
+ ocfs2_free_clusters(fs, n_clusters, blkno);
+ goto out_free_buf;
+ }
+
+ new_clusters -= n_clusters;
+ cpos += n_clusters;
+ }
+
+out_free_buf:
+ if (buf)
+ ocfs2_free(&buf);
+ return ret;
+}
+
+
errcode_t ocfs2_extend_allocation(ocfs2_filesys *fs, uint64_t ino,
uint32_t new_clusters)
{
@@ -3795,8 +3931,8 @@ errcode_t ocfs2_extend_allocation(ocfs2_filesys *fs, uint64_t ino,
if (ret)
break;
- ret = ocfs2_insert_extent(fs, ino, cpos, blkno, n_clusters,
- 0);
+ ret = ocfs2_inode_insert_extent(fs, ino, cpos, blkno,
+ n_clusters, 0);
if (ret) {
/* XXX: We don't wan't to overwrite the error
* from insert_extent(). But we probably need
diff --git a/libocfs2/xattr.c b/libocfs2/xattr.c
index d217ff0..c6f69c4 100644
--- a/libocfs2/xattr.c
+++ b/libocfs2/xattr.c
@@ -288,7 +288,8 @@ errcode_t ocfs2_xattr_get_rec(ocfs2_filesys *fs,
return OCFS2_ET_INVALID_ARGUMENT;
if (el->l_tree_depth) {
- ret = ocfs2_xattr_find_leaf(fs, xb, name_hash, &eb_buf);
+ ret = ocfs2_xattr_find_leaf(fs, el, xb->xb_blkno, (char *)xb,
+ name_hash, &eb_buf);
if (ret)
goto out;
diff --git a/tunefs.ocfs2/feature_sparse_files.c b/tunefs.ocfs2/feature_sparse_files.c
index ddb966f..f0dcea6 100644
--- a/tunefs.ocfs2/feature_sparse_files.c
+++ b/tunefs.ocfs2/feature_sparse_files.c
@@ -395,7 +395,7 @@ static errcode_t fill_one_hole(ocfs2_filesys *fs, struct sparse_file *file,
if (ret)
break;
- ret = ocfs2_insert_extent(fs, file->blkno,
+ ret = ocfs2_inode_insert_extent(fs, file->blkno,
start, p_start,
n_clusters, 0);
if (ret)
--
1.5.4.1
More information about the Ocfs2-tools-devel
mailing list