Given a physical cpos and length, decrement the refcount
in the tree. If the refcount for any portion of the extent goes
to zero, that portion is queued for freeing.
Signed-off-by: Tao Ma <tao.ma@oracle.com>
Given a physical cpos and length, increment the refcount
in the tree. If the extent has not been seen before, a refcount
record is created for it. Refcount records may be merged or
split by this operation.
Signed-off-by: Tao Ma <tao.ma@oracle.com>
Now fs/ocfs2/alloc.c has more than 7000 lines. It contains our
basic b-tree operation. Although we have already make our b-tree
operation generic, the basic structrue ocfs2_path which is used
to iterate one b-tree branch is still static and limited to only
used in alloc.c. As refcount tree need them and I don't want to
add any more b-tree unrelated code to alloc.c, export them out.
Signed-off-by: Tao Ma <tao.ma@oracle.com>
Add refcount b-tree as a new extent tree so that it can
use the b-tree to store and maniuplate ocfs2_refcount_rec.
Signed-off-by: Tao Ma <tao.ma@oracle.com>
ocfs2_mark_extent_written actually does the following things:
1. check the parameters.
2. initialize the left_path and split_rec.
3. call __ocfs2_mark_extent_written. it will do:
1) check the flags of unwritten
2) do the real split work.
The whole process is packed tightly somehow. So this patch
will abstract 2 different functions so that future b-tree
operation can work with it.
1. __ocfs2_split_extent will accept path and split_rec and do
the real split work.
2. ocfs2_change_extent_flag will accept a new flag and initialize
path and split_rec.
So now ocfs2_mark_extent_written will do:
1. check the parameters.
2. call ocfs2_change_extent_flag.
1) initalize the left_path and split_rec.
2) check whether the new flags conflict with the old one.
3) call __ocfs2_split_extent to do the split.
Signed-off-by: Tao Ma <tao.ma@oracle.com>
Add a new operation eo_ocfs2_extent_contig int the extent tree's
operations vector. So that with the new refcount tree, We want
this so that refcount trees can always return CONTIG_NONE and
prevent extent merging.
Signed-off-by: Tao Ma <tao.ma@oracle.com>
Implement locking around struct ocfs2_refcount_tree. This protects
all read/write operations on refcount trees. ocfs2_refcount_tree
has its own lock and its own caching_info, protecting buffers among
multiple nodes.
User must call ocfs2_lock_refcount_tree before his operation on
the tree and unlock it after that.
ocfs2_refcount_trees are referenced by the block number of the
refcount tree root block, So we create an rb-tree on the ocfs2_super
to look them up.
Signed-off-by: Tao Ma <tao.ma@oracle.com>
refcount tree should use its own caching info so that when
we downconvert the refcount tree lock, we can drop all the
cached buffer head.
Signed-off-by: Tao Ma <tao.ma@oracle.com>
In meta downconvert, we need to checkpoint the metadata in an inode.
For refcount tree, we also need it. So abstract the process out.
Signed-off-by: Tao Ma <tao.ma@oracle.com>
With this commit, extent tree operations are divorced from inodes and
rely on ocfs2_caching_info. Phew!
Signed-off-by: Joel Becker <joel.becker@oracle.com>
We only allow unwritten extents on data, so the toplevel
ocfs2_mark_extent_written() can use an inode all it wants. But the
subfunction isn't even using the inode argument.
Signed-off-by: Joel Becker <joel.becker@oracle.com>
ocfs2_insert_extent() wants to insert a record into the extent map if
it's an inode data extent. But since many btrees can call that
function, let's make it an op on ocfs2_extent_tree. Other tree types
can leave it empty.
Signed-off-by: Joel Becker <joel.becker@oracle.com>
ocfs2_remove_extent() wants to truncate the extent map if it's
truncating an inode data extent. But since many btrees can call that
function, let's make it an op on ocfs2_extent_tree. Other tree types
can leave it empty.
Signed-off-by: Joel Becker <joel.becker@oracle.com>
ocfs2_grow_branch() not really using it other than to pass it to the
subfunctions ocfs2_shift_tree_depth(), ocfs2_find_branch_target(), and
ocfs2_add_branch(). The first two weren't it either, so they drop the
argument. ocfs2_add_branch() only passed it to
ocfs2_adjust_rightmost_branch(), which drops the inode argument and uses
the ocfs2_extent_tree as well.
ocfs2_append_rec_to_path() can be take an ocfs2_extent_tree instead of
the inode. The function ocfs2_adjust_rightmost_records() goes along for
the ride.
Signed-off-by: Joel Becker <joel.becker@oracle.com>
It already gets ocfs2_extent_tree, so we can just use that. This chains
to the same modification for ocfs2_remove_rightmost_path() and
ocfs2_rotate_rightmost_leaf_left().
Signed-off-by: Joel Becker <joel.becker@oracle.com>
It already has struct ocfs2_extent_tree, which has the caching info. So
we don't need to pass it struct inode.
Signed-off-by: Joel Becker <joel.becker@oracle.com>
It already has struct ocfs2_extent_tree, which has the caching info. So
we don't need to pass it struct inode.
Signed-off-by: Joel Becker <joel.becker@oracle.com>
Get rid of the inode argument. Use extent_tree instead. This means a
few more functions have to pass an extent_tree around.
Signed-off-by: Joel Becker <joel.becker@oracle.com>
Pass the ocfs2_extent_list down through ocfs2_rotate_tree_right() and
get rid of struct inode in ocfs2_rotate_subtree_root_right().
Signed-off-by: Joel Becker <joel.becker@oracle.com>
Pass struct ocfs2_extent_tree into ocfs2_create_new_meta_bhs(). It no
longer needs struct inode or ocfs2_super.
Signed-off-by: Joel Becker <joel.becker@oracle.com>
ocfs2_find_path and ocfs2_find_leaf() walk our btrees, reading extent
blocks. They need struct ocfs2_caching_info for that, but not struct
inode.
Signed-off-by: Joel Becker <joel.becker@oracle.com>
extent blocks belong to btrees on more than just inodes, so we want to
pass the ocfs2_caching_info structure directly to
ocfs2_read_extent_block(). A number of places in alloc.c can now drop
struct inode from their argument list.
Signed-off-by: Joel Becker <joel.becker@oracle.com>
What do we cache? Metadata blocks. What are most of our non-inode metadata
blocks? Extent blocks for our btrees. struct ocfs2_extent_tree is the
main structure for managing those. So let's store the associated
ocfs2_caching_info there.
This means that ocfs2_et_root_journal_access() doesn't need struct inode
anymore, and any place that has an et can refer to et->et_ci instead of
INODE_CACHE(inode).
Signed-off-by: Joel Becker <joel.becker@oracle.com>
The next step in divorcing metadata I/O management from struct inode is
to pass struct ocfs2_caching_info to the journal functions. Thus the
journal locks a metadata cache with the cache io_lock function. It also
can compare ci_last_trans and ci_created_trans directly.
This is a large patch because of all the places we change
ocfs2_journal_access..(handle, inode, ...) to
ocfs2_journal_access..(handle, INODE_CACHE(inode), ...).
Signed-off-by: Joel Becker <joel.becker@oracle.com>