--- /dev/null
+From: Joel Becker <joel.becker@oracle.com>
+Subject: ocfs2: Change ocfs2_get_*_extent_tree() to ocfs2_init_*_extent_tree()
+Patch-mainline: 2.6.28?
+References: FATE302067
+
+The original get/put_extent_tree() functions held a reference on
+et_root_bh. However, every single caller already has a safe reference,
+making the get/put cycle irrelevant.
+
+We change ocfs2_get_*_extent_tree() to ocfs2_init_*_extent_tree(). It
+no longer gets a reference on et_root_bh. ocfs2_put_extent_tree() is
+removed. Callers now have a simpler init+use pattern.
+
+Signed-off-by: Joel Becker <joel.becker@oracle.com>
+Acked-by: Mark Fasheh <mark.fasheh@suse.com>
+---
+ fs/ocfs2/alloc.c | 49 +++++++++++++++++++++----------------------------
+ fs/ocfs2/alloc.h | 26 ++++++++++++--------------
+ fs/ocfs2/aops.c | 6 ++----
+ fs/ocfs2/dir.c | 6 ++----
+ fs/ocfs2/file.c | 10 +++-------
+ fs/ocfs2/xattr.c | 14 ++++----------
+ 6 files changed, 44 insertions(+), 67 deletions(-)
+
+--- a/fs/ocfs2/alloc.c
++++ b/fs/ocfs2/alloc.c
+@@ -55,7 +55,7 @@
+ *
+ * To implement an on-disk btree (extent tree) type in ocfs2, add
+ * an ocfs2_extent_tree_operations structure and the matching
+- * ocfs2_get_<thingy>_extent_tree() function. That's pretty much it
++ * ocfs2_init_<thingy>_extent_tree() function. That's pretty much it
+ * for the allocation portion of the extent tree.
+ */
+ struct ocfs2_extent_tree_operations {
+@@ -301,14 +301,13 @@ static struct ocfs2_extent_tree_operatio
+ .eo_fill_max_leaf_clusters = ocfs2_xattr_tree_fill_max_leaf_clusters,
+ };
+
+-static void __ocfs2_get_extent_tree(struct ocfs2_extent_tree *et,
+- struct inode *inode,
+- struct buffer_head *bh,
+- void *obj,
+- struct ocfs2_extent_tree_operations *ops)
++static void __ocfs2_init_extent_tree(struct ocfs2_extent_tree *et,
++ struct inode *inode,
++ struct buffer_head *bh,
++ void *obj,
++ struct ocfs2_extent_tree_operations *ops)
+ {
+ et->et_ops = ops;
+- get_bh(bh);
+ et->et_root_bh = bh;
+ if (!obj)
+ obj = (void *)bh->b_data;
+@@ -321,33 +320,28 @@ static void __ocfs2_get_extent_tree(stru
+ et->et_ops->eo_fill_max_leaf_clusters(inode, et);
+ }
+
+-void ocfs2_get_dinode_extent_tree(struct ocfs2_extent_tree *et,
+- struct inode *inode,
+- struct buffer_head *bh)
+-{
+- __ocfs2_get_extent_tree(et, inode, bh, NULL, &ocfs2_dinode_et_ops);
+-}
+-
+-void ocfs2_get_xattr_tree_extent_tree(struct ocfs2_extent_tree *et,
+- struct inode *inode,
+- struct buffer_head *bh)
++void ocfs2_init_dinode_extent_tree(struct ocfs2_extent_tree *et,
++ struct inode *inode,
++ struct buffer_head *bh)
+ {
+- __ocfs2_get_extent_tree(et, inode, bh, NULL,
+- &ocfs2_xattr_tree_et_ops);
++ __ocfs2_init_extent_tree(et, inode, bh, NULL, &ocfs2_dinode_et_ops);
+ }
+
+-void ocfs2_get_xattr_value_extent_tree(struct ocfs2_extent_tree *et,
++void ocfs2_init_xattr_tree_extent_tree(struct ocfs2_extent_tree *et,
+ struct inode *inode,
+- struct buffer_head *bh,
+- struct ocfs2_xattr_value_root *xv)
++ struct buffer_head *bh)
+ {
+- __ocfs2_get_extent_tree(et, inode, bh, xv,
+- &ocfs2_xattr_value_et_ops);
++ __ocfs2_init_extent_tree(et, inode, bh, NULL,
++ &ocfs2_xattr_tree_et_ops);
+ }
+
+-void ocfs2_put_extent_tree(struct ocfs2_extent_tree *et)
++void ocfs2_init_xattr_value_extent_tree(struct ocfs2_extent_tree *et,
++ struct inode *inode,
++ struct buffer_head *bh,
++ struct ocfs2_xattr_value_root *xv)
+ {
+- brelse(et->et_root_bh);
++ __ocfs2_init_extent_tree(et, inode, bh, xv,
++ &ocfs2_xattr_value_et_ops);
+ }
+
+ static inline void ocfs2_et_set_last_eb_blk(struct ocfs2_extent_tree *et,
+@@ -6800,10 +6794,9 @@ int ocfs2_convert_inline_data_to_extents
+ * this proves to be false, we could always re-build
+ * the in-inode data from our pages.
+ */
+- ocfs2_get_dinode_extent_tree(&et, inode, di_bh);
++ ocfs2_init_dinode_extent_tree(&et, inode, di_bh);
+ ret = ocfs2_insert_extent(osb, handle, inode, &et,
+ 0, block, 1, 0, NULL);
+- ocfs2_put_extent_tree(&et);
+ if (ret) {
+ mlog_errno(ret);
+ goto out_commit;
+--- a/fs/ocfs2/alloc.h
++++ b/fs/ocfs2/alloc.h
+@@ -41,7 +41,7 @@
+ *
+ * ocfs2_extent_tree becomes the first-class object for extent tree
+ * manipulation. Callers of the alloc.c code need to fill it via one of
+- * the ocfs2_get_*_extent_tree() operations below.
++ * the ocfs2_init_*_extent_tree() operations below.
+ *
+ * ocfs2_extent_tree contains info for the root of the b-tree, it must have a
+ * root ocfs2_extent_list and a root_bh so that they can be used in the b-tree
+@@ -59,21 +59,19 @@ struct ocfs2_extent_tree {
+ };
+
+ /*
+- * ocfs2_*_get_extent_tree() will fill an ocfs2_extent_tree from the
+- * specified object buffer. The bh is referenced until
+- * ocfs2_put_extent_tree().
++ * ocfs2_init_*_extent_tree() will fill an ocfs2_extent_tree from the
++ * specified object buffer.
+ */
+-void ocfs2_get_dinode_extent_tree(struct ocfs2_extent_tree *et,
+- struct inode *inode,
+- struct buffer_head *bh);
+-void ocfs2_get_xattr_tree_extent_tree(struct ocfs2_extent_tree *et,
+- struct inode *inode,
+- struct buffer_head *bh);
+-void ocfs2_get_xattr_value_extent_tree(struct ocfs2_extent_tree *et,
++void ocfs2_init_dinode_extent_tree(struct ocfs2_extent_tree *et,
++ struct inode *inode,
++ struct buffer_head *bh);
++void ocfs2_init_xattr_tree_extent_tree(struct ocfs2_extent_tree *et,
+ struct inode *inode,
+- struct buffer_head *bh,
+- struct ocfs2_xattr_value_root *xv);
+-void ocfs2_put_extent_tree(struct ocfs2_extent_tree *et);
++ struct buffer_head *bh);
++void ocfs2_init_xattr_value_extent_tree(struct ocfs2_extent_tree *et,
++ struct inode *inode,
++ struct buffer_head *bh,
++ struct ocfs2_xattr_value_root *xv);
+
+ struct ocfs2_alloc_context;
+ int ocfs2_insert_extent(struct ocfs2_super *osb,
+--- a/fs/ocfs2/aops.c
++++ b/fs/ocfs2/aops.c
+@@ -1277,11 +1277,10 @@ static int ocfs2_write_cluster(struct ad
+ goto out;
+ }
+ } else if (unwritten) {
+- ocfs2_get_dinode_extent_tree(&et, inode, wc->w_di_bh);
++ ocfs2_init_dinode_extent_tree(&et, inode, wc->w_di_bh);
+ ret = ocfs2_mark_extent_written(inode, &et,
+ wc->w_handle, cpos, 1, phys,
+ meta_ac, &wc->w_dealloc);
+- ocfs2_put_extent_tree(&et);
+ if (ret < 0) {
+ mlog_errno(ret);
+ goto out;
+@@ -1722,11 +1721,10 @@ int ocfs2_write_begin_nolock(struct addr
+ (long long)i_size_read(inode), le32_to_cpu(di->i_clusters),
+ clusters_to_alloc, extents_to_split);
+
+- ocfs2_get_dinode_extent_tree(&et, inode, wc->w_di_bh);
++ ocfs2_init_dinode_extent_tree(&et, inode, wc->w_di_bh);
+ ret = ocfs2_lock_allocators(inode, &et,
+ clusters_to_alloc, extents_to_split,
+ &data_ac, &meta_ac);
+- ocfs2_put_extent_tree(&et);
+ if (ret) {
+ mlog_errno(ret);
+ goto out;
+--- a/fs/ocfs2/dir.c
++++ b/fs/ocfs2/dir.c
+@@ -1194,7 +1194,7 @@ static int ocfs2_expand_inline_dir(struc
+ handle_t *handle;
+ struct ocfs2_extent_tree et;
+
+- ocfs2_get_dinode_extent_tree(&et, dir, di_bh);
++ ocfs2_init_dinode_extent_tree(&et, dir, di_bh);
+
+ alloc = ocfs2_clusters_for_bytes(sb, bytes);
+
+@@ -1363,7 +1363,6 @@ out:
+
+ brelse(dirdata_bh);
+
+- ocfs2_put_extent_tree(&et);
+ return ret;
+ }
+
+@@ -1485,9 +1484,8 @@ static int ocfs2_extend_dir(struct ocfs2
+ spin_lock(&OCFS2_I(dir)->ip_lock);
+ if (dir_i_size == ocfs2_clusters_to_bytes(sb, OCFS2_I(dir)->ip_clusters)) {
+ spin_unlock(&OCFS2_I(dir)->ip_lock);
+- ocfs2_get_dinode_extent_tree(&et, dir, parent_fe_bh);
++ ocfs2_init_dinode_extent_tree(&et, dir, parent_fe_bh);
+ num_free_extents = ocfs2_num_free_extents(osb, dir, &et);
+- ocfs2_put_extent_tree(&et);
+ if (num_free_extents < 0) {
+ status = num_free_extents;
+ mlog_errno(status);
+--- a/fs/ocfs2/file.c
++++ b/fs/ocfs2/file.c
+@@ -512,12 +512,11 @@ int ocfs2_add_inode_data(struct ocfs2_su
+ int ret;
+ struct ocfs2_extent_tree et;
+
+- ocfs2_get_dinode_extent_tree(&et, inode, fe_bh);
++ ocfs2_init_dinode_extent_tree(&et, inode, fe_bh);
+ ret = ocfs2_add_clusters_in_btree(osb, inode, logical_offset,
+ clusters_to_add, mark_unwritten,
+ &et, handle,
+ data_ac, meta_ac, reason_ret);
+- ocfs2_put_extent_tree(&et);
+
+ return ret;
+ }
+@@ -568,10 +567,9 @@ restart_all:
+ (unsigned long long)OCFS2_I(inode)->ip_blkno,
+ (long long)i_size_read(inode), le32_to_cpu(fe->i_clusters),
+ clusters_to_add);
+- ocfs2_get_dinode_extent_tree(&et, inode, bh);
++ ocfs2_init_dinode_extent_tree(&et, inode, bh);
+ status = ocfs2_lock_allocators(inode, &et, clusters_to_add, 0,
+ &data_ac, &meta_ac);
+- ocfs2_put_extent_tree(&et);
+ if (status) {
+ mlog_errno(status);
+ goto leave;
+@@ -1243,11 +1241,10 @@ static int __ocfs2_remove_inode_range(st
+ struct ocfs2_dinode *di = (struct ocfs2_dinode *)di_bh->b_data;
+ struct ocfs2_extent_tree et;
+
+- ocfs2_get_dinode_extent_tree(&et, inode, di_bh);
++ ocfs2_init_dinode_extent_tree(&et, inode, di_bh);
+
+ ret = ocfs2_lock_allocators(inode, &et, 0, 1, NULL, &meta_ac);
+ if (ret) {
+- ocfs2_put_extent_tree(&et);
+ mlog_errno(ret);
+ return ret;
+ }
+@@ -1304,7 +1301,6 @@ out:
+ if (meta_ac)
+ ocfs2_free_alloc_context(meta_ac);
+
+- ocfs2_put_extent_tree(&et);
+ return ret;
+ }
+
+--- a/fs/ocfs2/xattr.c
++++ b/fs/ocfs2/xattr.c
+@@ -227,7 +227,7 @@ static int ocfs2_xattr_extend_allocation
+
+ mlog(0, "(clusters_to_add for xattr= %u)\n", clusters_to_add);
+
+- ocfs2_get_xattr_value_extent_tree(&et, inode, xattr_bh, xv);
++ ocfs2_init_xattr_value_extent_tree(&et, inode, xattr_bh, xv);
+
+ restart_all:
+
+@@ -323,7 +323,6 @@ leave:
+ goto restart_all;
+ }
+
+- ocfs2_put_extent_tree(&et);
+ return status;
+ }
+
+@@ -341,11 +340,10 @@ static int __ocfs2_remove_xattr_range(st
+ struct ocfs2_alloc_context *meta_ac = NULL;
+ struct ocfs2_extent_tree et;
+
+- ocfs2_get_xattr_value_extent_tree(&et, inode, root_bh, xv);
++ ocfs2_init_xattr_value_extent_tree(&et, inode, root_bh, xv);
+
+ ret = ocfs2_lock_allocators(inode, &et, 0, 1, NULL, &meta_ac);
+ if (ret) {
+- ocfs2_put_extent_tree(&et);
+ mlog_errno(ret);
+ return ret;
+ }
+@@ -401,7 +399,6 @@ out:
+ if (meta_ac)
+ ocfs2_free_alloc_context(meta_ac);
+
+- ocfs2_put_extent_tree(&et);
+ return ret;
+ }
+
+@@ -3648,7 +3645,7 @@ static int ocfs2_add_new_xattr_cluster(s
+ (unsigned long long)OCFS2_I(inode)->ip_blkno,
+ prev_cpos, prev_blkno);
+
+- ocfs2_get_xattr_tree_extent_tree(&et, inode, root_bh);
++ ocfs2_init_xattr_tree_extent_tree(&et, inode, root_bh);
+
+ ret = ocfs2_lock_allocators(inode, &et, clusters_to_add, 0,
+ &data_ac, &meta_ac);
+@@ -3743,7 +3740,6 @@ leave:
+ if (meta_ac)
+ ocfs2_free_alloc_context(meta_ac);
+
+- ocfs2_put_extent_tree(&et);
+ return ret;
+ }
+
+@@ -4352,7 +4348,7 @@ static int ocfs2_rm_xattr_cluster(struct
+ struct ocfs2_cached_dealloc_ctxt dealloc;
+ struct ocfs2_extent_tree et;
+
+- ocfs2_get_xattr_tree_extent_tree(&et, inode, root_bh);
++ ocfs2_init_xattr_tree_extent_tree(&et, inode, root_bh);
+
+ ocfs2_init_dealloc_ctxt(&dealloc);
+
+@@ -4363,7 +4359,6 @@ static int ocfs2_rm_xattr_cluster(struct
+
+ ret = ocfs2_lock_allocators(inode, &et, 0, 1, NULL, &meta_ac);
+ if (ret) {
+- ocfs2_put_extent_tree(&et);
+ mlog_errno(ret);
+ return ret;
+ }
+@@ -4423,7 +4418,6 @@ out:
+
+ ocfs2_run_deallocs(osb, &dealloc);
+
+- ocfs2_put_extent_tree(&et);
+ return ret;
+ }
+