瀏覽代碼

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>
Mark Fasheh 18 年之前
父節點
當前提交
328d5752e1
共有 6 個文件被更改,包括 1413 次插入206 次删除
  1. 1383 174
      fs/ocfs2/alloc.c
  2. 6 0
      fs/ocfs2/alloc.h
  3. 5 0
      fs/ocfs2/endian.h
  4. 0 31
      fs/ocfs2/extent_map.c
  5. 13 0
      fs/ocfs2/ocfs2.h
  6. 6 1
      fs/ocfs2/ocfs2_fs.h

File diff suppressed because it is too large
+ 1383 - 174
fs/ocfs2/alloc.c


+ 6 - 0
fs/ocfs2/alloc.h

@@ -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.

+ 5 - 0
fs/ocfs2/endian.h

@@ -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);

+ 0 - 31
fs/ocfs2/extent_map.c

@@ -373,37 +373,6 @@ out:
 	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)

+ 13 - 0
fs/ocfs2/ocfs2.h

@@ -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

+ 6 - 1
fs/ocfs2/ocfs2_fs.h

@@ -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.
  */
  */

Some files were not shown because too many files changed in this diff