ocfs2: btree changes for unwritten extents
Writes to a region marked as unwritten might result in a record split or merge. We can support splits by making minor changes to the existing insert code. Merges require left rotations which mostly re-use right rotation support functions. Signed-off-by: Mark Fasheh <mark.fasheh@oracle.com>
This commit is contained in:
parent
c3afcbb344
commit
328d5752e1
6 changed files with 1770 additions and 91 deletions
1799
fs/ocfs2/alloc.c
1799
fs/ocfs2/alloc.c
File diff suppressed because it is too large
Load diff
|
@ -35,6 +35,11 @@ int ocfs2_insert_extent(struct ocfs2_super *osb,
|
||||||
u64 start_blk,
|
u64 start_blk,
|
||||||
u32 new_clusters,
|
u32 new_clusters,
|
||||||
struct ocfs2_alloc_context *meta_ac);
|
struct ocfs2_alloc_context *meta_ac);
|
||||||
|
struct ocfs2_cached_dealloc_ctxt;
|
||||||
|
int ocfs2_mark_extent_written(struct inode *inode, struct buffer_head *di_bh,
|
||||||
|
handle_t *handle, u32 cpos, u32 len, u32 phys,
|
||||||
|
struct ocfs2_alloc_context *meta_ac,
|
||||||
|
struct ocfs2_cached_dealloc_ctxt *dealloc);
|
||||||
int ocfs2_num_free_extents(struct ocfs2_super *osb,
|
int ocfs2_num_free_extents(struct ocfs2_super *osb,
|
||||||
struct inode *inode,
|
struct inode *inode,
|
||||||
struct ocfs2_dinode *fe);
|
struct ocfs2_dinode *fe);
|
||||||
|
@ -102,6 +107,7 @@ int ocfs2_commit_truncate(struct ocfs2_super *osb,
|
||||||
|
|
||||||
int ocfs2_find_leaf(struct inode *inode, struct ocfs2_extent_list *root_el,
|
int ocfs2_find_leaf(struct inode *inode, struct ocfs2_extent_list *root_el,
|
||||||
u32 cpos, struct buffer_head **leaf_bh);
|
u32 cpos, struct buffer_head **leaf_bh);
|
||||||
|
int ocfs2_search_extent_list(struct ocfs2_extent_list *el, u32 v_cluster);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Helper function to look at the # of clusters in an extent record.
|
* Helper function to look at the # of clusters in an extent record.
|
||||||
|
|
|
@ -32,6 +32,11 @@ static inline void le32_add_cpu(__le32 *var, u32 val)
|
||||||
*var = cpu_to_le32(le32_to_cpu(*var) + val);
|
*var = cpu_to_le32(le32_to_cpu(*var) + val);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void le64_add_cpu(__le64 *var, u64 val)
|
||||||
|
{
|
||||||
|
*var = cpu_to_le64(le64_to_cpu(*var) + val);
|
||||||
|
}
|
||||||
|
|
||||||
static inline void le32_and_cpu(__le32 *var, u32 val)
|
static inline void le32_and_cpu(__le32 *var, u32 val)
|
||||||
{
|
{
|
||||||
*var = cpu_to_le32(le32_to_cpu(*var) & val);
|
*var = cpu_to_le32(le32_to_cpu(*var) & val);
|
||||||
|
|
|
@ -373,37 +373,6 @@ static int ocfs2_figure_hole_clusters(struct inode *inode,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Return the index of the extent record which contains cluster #v_cluster.
|
|
||||||
* -1 is returned if it was not found.
|
|
||||||
*
|
|
||||||
* Should work fine on interior and exterior nodes.
|
|
||||||
*/
|
|
||||||
static int ocfs2_search_extent_list(struct ocfs2_extent_list *el,
|
|
||||||
u32 v_cluster)
|
|
||||||
{
|
|
||||||
int ret = -1;
|
|
||||||
int i;
|
|
||||||
struct ocfs2_extent_rec *rec;
|
|
||||||
u32 rec_end, rec_start, clusters;
|
|
||||||
|
|
||||||
for(i = 0; i < le16_to_cpu(el->l_next_free_rec); i++) {
|
|
||||||
rec = &el->l_recs[i];
|
|
||||||
|
|
||||||
rec_start = le32_to_cpu(rec->e_cpos);
|
|
||||||
clusters = ocfs2_rec_clusters(el, rec);
|
|
||||||
|
|
||||||
rec_end = rec_start + clusters;
|
|
||||||
|
|
||||||
if (v_cluster >= rec_start && v_cluster < rec_end) {
|
|
||||||
ret = i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
int ocfs2_get_clusters(struct inode *inode, u32 v_cluster,
|
int ocfs2_get_clusters(struct inode *inode, u32 v_cluster,
|
||||||
u32 *p_cluster, u32 *num_clusters,
|
u32 *p_cluster, u32 *num_clusters,
|
||||||
unsigned int *extent_flags)
|
unsigned int *extent_flags)
|
||||||
|
|
|
@ -306,6 +306,19 @@ static inline int ocfs2_sparse_alloc(struct ocfs2_super *osb)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline int ocfs2_writes_unwritten_extents(struct ocfs2_super *osb)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Support for sparse files is a pre-requisite
|
||||||
|
*/
|
||||||
|
if (!ocfs2_sparse_alloc(osb))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (osb->s_feature_ro_compat & OCFS2_FEATURE_RO_COMPAT_UNWRITTEN)
|
||||||
|
return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* set / clear functions because cluster events can make these happen
|
/* set / clear functions because cluster events can make these happen
|
||||||
* in parallel so we want the transitions to be atomic. this also
|
* in parallel so we want the transitions to be atomic. this also
|
||||||
* means that any future flags osb_flags must be protected by spinlock
|
* means that any future flags osb_flags must be protected by spinlock
|
||||||
|
|
|
@ -88,7 +88,7 @@
|
||||||
#define OCFS2_FEATURE_COMPAT_SUPP OCFS2_FEATURE_COMPAT_BACKUP_SB
|
#define OCFS2_FEATURE_COMPAT_SUPP OCFS2_FEATURE_COMPAT_BACKUP_SB
|
||||||
#define OCFS2_FEATURE_INCOMPAT_SUPP (OCFS2_FEATURE_INCOMPAT_LOCAL_MOUNT \
|
#define OCFS2_FEATURE_INCOMPAT_SUPP (OCFS2_FEATURE_INCOMPAT_LOCAL_MOUNT \
|
||||||
| OCFS2_FEATURE_INCOMPAT_SPARSE_ALLOC)
|
| OCFS2_FEATURE_INCOMPAT_SPARSE_ALLOC)
|
||||||
#define OCFS2_FEATURE_RO_COMPAT_SUPP 0
|
#define OCFS2_FEATURE_RO_COMPAT_SUPP OCFS2_FEATURE_RO_COMPAT_UNWRITTEN
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Heartbeat-only devices are missing journals and other files. The
|
* Heartbeat-only devices are missing journals and other files. The
|
||||||
|
@ -116,6 +116,11 @@
|
||||||
*/
|
*/
|
||||||
#define OCFS2_FEATURE_COMPAT_BACKUP_SB 0x0001
|
#define OCFS2_FEATURE_COMPAT_BACKUP_SB 0x0001
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Unwritten extents support.
|
||||||
|
*/
|
||||||
|
#define OCFS2_FEATURE_RO_COMPAT_UNWRITTEN 0x0001
|
||||||
|
|
||||||
/* The byte offset of the first backup block will be 1G.
|
/* The byte offset of the first backup block will be 1G.
|
||||||
* The following will be 4G, 16G, 64G, 256G and 1T.
|
* The following will be 4G, 16G, 64G, 256G and 1T.
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Reference in a new issue