nilfs2: remove bmap pointer operations

Previously, the bmap codes of nilfs used three types of function
tables.  The abuse of indirect function calls decreased source
readability and suffered many indirect jumps which would confuse
branch prediction of processors.

This eliminates one type of the function tables,
nilfs_bmap_ptr_operations, which was used to dispatch low level
pointer operations of the nilfs bmap.

This adds a new integer variable "b_ptr_type" to nilfs_bmap struct,
and uses the value to select the pointer operations.

Signed-off-by: Ryusuke Konishi <konishi.ryusuke@lab.ntt.co.jp>
diff --git a/fs/nilfs2/bmap.c b/fs/nilfs2/bmap.c
index de67d2a..51824c7 100644
--- a/fs/nilfs2/bmap.c
+++ b/fs/nilfs2/bmap.c
@@ -31,21 +31,26 @@
 #include "dat.h"
 #include "alloc.h"
 
+static struct inode *nilfs_bmap_get_dat(const struct nilfs_bmap *bmap)
+{
+	return nilfs_dat_inode(NILFS_I_NILFS(bmap->b_inode));
+}
+
 int nilfs_bmap_lookup_at_level(struct nilfs_bmap *bmap, __u64 key, int level,
 			       __u64 *ptrp)
 {
-	__u64 ptr;
+	sector_t blocknr;
 	int ret;
 
 	down_read(&bmap->b_sem);
 	ret = bmap->b_ops->bop_lookup(bmap, key, level, ptrp);
 	if (ret < 0)
 		goto out;
-	if (bmap->b_pops->bpop_translate != NULL) {
-		ret = bmap->b_pops->bpop_translate(bmap, *ptrp, &ptr);
-		if (ret < 0)
-			goto out;
-		*ptrp = ptr;
+	if (NILFS_BMAP_USE_VBN(bmap)) {
+		ret = nilfs_dat_translate(nilfs_bmap_get_dat(bmap), *ptrp,
+					  &blocknr);
+		if (!ret)
+			*ptrp = blocknr;
 	}
 
  out:
@@ -442,11 +447,6 @@
 		return NILFS_BMAP_INVALID_PTR;
 }
 
-static struct inode *nilfs_bmap_get_dat(const struct nilfs_bmap *bmap)
-{
-	return nilfs_dat_inode(NILFS_I_NILFS(bmap->b_inode));
-}
-
 #define NILFS_BMAP_GROUP_DIV	8
 __u64 nilfs_bmap_find_target_in_group(const struct nilfs_bmap *bmap)
 {
@@ -459,20 +459,20 @@
 		(entries_per_group / NILFS_BMAP_GROUP_DIV);
 }
 
-static int nilfs_bmap_prepare_alloc_v(struct nilfs_bmap *bmap,
-				      union nilfs_bmap_ptr_req *req)
+int nilfs_bmap_prepare_alloc_v(struct nilfs_bmap *bmap,
+				 union nilfs_bmap_ptr_req *req)
 {
 	return nilfs_dat_prepare_alloc(nilfs_bmap_get_dat(bmap), &req->bpr_req);
 }
 
-static void nilfs_bmap_commit_alloc_v(struct nilfs_bmap *bmap,
-				      union nilfs_bmap_ptr_req *req)
+void nilfs_bmap_commit_alloc_v(struct nilfs_bmap *bmap,
+				 union nilfs_bmap_ptr_req *req)
 {
 	nilfs_dat_commit_alloc(nilfs_bmap_get_dat(bmap), &req->bpr_req);
 }
 
-static void nilfs_bmap_abort_alloc_v(struct nilfs_bmap *bmap,
-				     union nilfs_bmap_ptr_req *req)
+void nilfs_bmap_abort_alloc_v(struct nilfs_bmap *bmap,
+			      union nilfs_bmap_ptr_req *req)
 {
 	nilfs_dat_abort_alloc(nilfs_bmap_get_dat(bmap), &req->bpr_req);
 }
@@ -489,26 +489,21 @@
 	return ret;
 }
 
-static int nilfs_bmap_prepare_end_v(struct nilfs_bmap *bmap,
-				    union nilfs_bmap_ptr_req *req)
+int nilfs_bmap_prepare_end_v(struct nilfs_bmap *bmap,
+			     union nilfs_bmap_ptr_req *req)
 {
 	return nilfs_dat_prepare_end(nilfs_bmap_get_dat(bmap), &req->bpr_req);
 }
 
-static void nilfs_bmap_commit_end_v(struct nilfs_bmap *bmap,
-				    union nilfs_bmap_ptr_req *req)
+void nilfs_bmap_commit_end_v(struct nilfs_bmap *bmap,
+			     union nilfs_bmap_ptr_req *req)
 {
-	nilfs_dat_commit_end(nilfs_bmap_get_dat(bmap), &req->bpr_req, 0);
+	nilfs_dat_commit_end(nilfs_bmap_get_dat(bmap), &req->bpr_req,
+			     bmap->b_ptr_type == NILFS_BMAP_PTR_VS);
 }
 
-static void nilfs_bmap_commit_end_vmdt(struct nilfs_bmap *bmap,
-				       union nilfs_bmap_ptr_req *req)
-{
-	nilfs_dat_commit_end(nilfs_bmap_get_dat(bmap), &req->bpr_req, 1);
-}
-
-static void nilfs_bmap_abort_end_v(struct nilfs_bmap *bmap,
-				   union nilfs_bmap_ptr_req *req)
+void nilfs_bmap_abort_end_v(struct nilfs_bmap *bmap,
+			    union nilfs_bmap_ptr_req *req)
 {
 	nilfs_dat_abort_end(nilfs_bmap_get_dat(bmap), &req->bpr_req);
 }
@@ -524,116 +519,44 @@
 	return nilfs_dat_mark_dirty(nilfs_bmap_get_dat(bmap), vblocknr);
 }
 
-int nilfs_bmap_prepare_update(struct nilfs_bmap *bmap,
-			      union nilfs_bmap_ptr_req *oldreq,
-			      union nilfs_bmap_ptr_req *newreq)
+int nilfs_bmap_prepare_update_v(struct nilfs_bmap *bmap,
+				union nilfs_bmap_ptr_req *oldreq,
+				union nilfs_bmap_ptr_req *newreq)
 {
+	struct inode *dat = nilfs_bmap_get_dat(bmap);
 	int ret;
 
-	ret = bmap->b_pops->bpop_prepare_end_ptr(bmap, oldreq);
+	ret = nilfs_dat_prepare_end(dat, &oldreq->bpr_req);
 	if (ret < 0)
 		return ret;
-	ret = bmap->b_pops->bpop_prepare_alloc_ptr(bmap, newreq);
+	ret = nilfs_dat_prepare_alloc(dat, &newreq->bpr_req);
 	if (ret < 0)
-		bmap->b_pops->bpop_abort_end_ptr(bmap, oldreq);
+		nilfs_dat_abort_end(dat, &oldreq->bpr_req);
 
 	return ret;
 }
 
-void nilfs_bmap_commit_update(struct nilfs_bmap *bmap,
-			      union nilfs_bmap_ptr_req *oldreq,
-			      union nilfs_bmap_ptr_req *newreq)
+void nilfs_bmap_commit_update_v(struct nilfs_bmap *bmap,
+				union nilfs_bmap_ptr_req *oldreq,
+				union nilfs_bmap_ptr_req *newreq)
 {
-	bmap->b_pops->bpop_commit_end_ptr(bmap, oldreq);
-	bmap->b_pops->bpop_commit_alloc_ptr(bmap, newreq);
+	struct inode *dat = nilfs_bmap_get_dat(bmap);
+
+	nilfs_dat_commit_end(dat, &oldreq->bpr_req,
+			     bmap->b_ptr_type == NILFS_BMAP_PTR_VS);
+	nilfs_dat_commit_alloc(dat, &newreq->bpr_req);
 }
 
-void nilfs_bmap_abort_update(struct nilfs_bmap *bmap,
-			     union nilfs_bmap_ptr_req *oldreq,
-			     union nilfs_bmap_ptr_req *newreq)
+void nilfs_bmap_abort_update_v(struct nilfs_bmap *bmap,
+			       union nilfs_bmap_ptr_req *oldreq,
+			       union nilfs_bmap_ptr_req *newreq)
 {
-	bmap->b_pops->bpop_abort_end_ptr(bmap, oldreq);
-	bmap->b_pops->bpop_abort_alloc_ptr(bmap, newreq);
+	struct inode *dat = nilfs_bmap_get_dat(bmap);
+
+	nilfs_dat_abort_end(dat, &oldreq->bpr_req);
+	nilfs_dat_abort_alloc(dat, &newreq->bpr_req);
 }
 
-static int nilfs_bmap_translate_v(const struct nilfs_bmap *bmap, __u64 ptr,
-				  __u64 *ptrp)
-{
-	sector_t blocknr;
-	int ret;
-
-	ret = nilfs_dat_translate(nilfs_bmap_get_dat(bmap), ptr, &blocknr);
-	if (ret < 0)
-		return ret;
-	if (ptrp != NULL)
-		*ptrp = blocknr;
-	return 0;
-}
-
-static int nilfs_bmap_prepare_alloc_p(struct nilfs_bmap *bmap,
-				      union nilfs_bmap_ptr_req *req)
-{
-	/* ignore target ptr */
-	req->bpr_ptr = bmap->b_last_allocated_ptr++;
-	return 0;
-}
-
-static void nilfs_bmap_commit_alloc_p(struct nilfs_bmap *bmap,
-				      union nilfs_bmap_ptr_req *req)
-{
-	/* do nothing */
-}
-
-static void nilfs_bmap_abort_alloc_p(struct nilfs_bmap *bmap,
-				     union nilfs_bmap_ptr_req *req)
-{
-	bmap->b_last_allocated_ptr--;
-}
-
-static const struct nilfs_bmap_ptr_operations nilfs_bmap_ptr_ops_v = {
-	.bpop_prepare_alloc_ptr	=	nilfs_bmap_prepare_alloc_v,
-	.bpop_commit_alloc_ptr	=	nilfs_bmap_commit_alloc_v,
-	.bpop_abort_alloc_ptr	=	nilfs_bmap_abort_alloc_v,
-	.bpop_prepare_end_ptr	=	nilfs_bmap_prepare_end_v,
-	.bpop_commit_end_ptr	=	nilfs_bmap_commit_end_v,
-	.bpop_abort_end_ptr	=	nilfs_bmap_abort_end_v,
-
-	.bpop_translate		=	nilfs_bmap_translate_v,
-};
-
-static const struct nilfs_bmap_ptr_operations nilfs_bmap_ptr_ops_vmdt = {
-	.bpop_prepare_alloc_ptr	=	nilfs_bmap_prepare_alloc_v,
-	.bpop_commit_alloc_ptr	=	nilfs_bmap_commit_alloc_v,
-	.bpop_abort_alloc_ptr	=	nilfs_bmap_abort_alloc_v,
-	.bpop_prepare_end_ptr	=	nilfs_bmap_prepare_end_v,
-	.bpop_commit_end_ptr	=	nilfs_bmap_commit_end_vmdt,
-	.bpop_abort_end_ptr	=	nilfs_bmap_abort_end_v,
-
-	.bpop_translate		=	nilfs_bmap_translate_v,
-};
-
-static const struct nilfs_bmap_ptr_operations nilfs_bmap_ptr_ops_p = {
-	.bpop_prepare_alloc_ptr	=	nilfs_bmap_prepare_alloc_p,
-	.bpop_commit_alloc_ptr	=	nilfs_bmap_commit_alloc_p,
-	.bpop_abort_alloc_ptr	=	nilfs_bmap_abort_alloc_p,
-	.bpop_prepare_end_ptr	=	NULL,
-	.bpop_commit_end_ptr	=	NULL,
-	.bpop_abort_end_ptr	=	NULL,
-
-	.bpop_translate		=	NULL,
-};
-
-static const struct nilfs_bmap_ptr_operations nilfs_bmap_ptr_ops_gc = {
-	.bpop_prepare_alloc_ptr	=	NULL,
-	.bpop_commit_alloc_ptr	=	NULL,
-	.bpop_abort_alloc_ptr	=	NULL,
-	.bpop_prepare_end_ptr	=	NULL,
-	.bpop_commit_end_ptr	=	NULL,
-	.bpop_abort_end_ptr	=	NULL,
-
-	.bpop_translate		=	NULL,
-};
-
 static struct lock_class_key nilfs_bmap_dat_lock_key;
 
 /**
@@ -660,20 +583,20 @@
 	bmap->b_inode = &NILFS_BMAP_I(bmap)->vfs_inode;
 	switch (bmap->b_inode->i_ino) {
 	case NILFS_DAT_INO:
-		bmap->b_pops = &nilfs_bmap_ptr_ops_p;
-		bmap->b_last_allocated_key = 0;	/* XXX: use macro */
+		bmap->b_ptr_type = NILFS_BMAP_PTR_P;
+		bmap->b_last_allocated_key = 0;
 		bmap->b_last_allocated_ptr = NILFS_BMAP_NEW_PTR_INIT;
 		lockdep_set_class(&bmap->b_sem, &nilfs_bmap_dat_lock_key);
 		break;
 	case NILFS_CPFILE_INO:
 	case NILFS_SUFILE_INO:
-		bmap->b_pops = &nilfs_bmap_ptr_ops_vmdt;
-		bmap->b_last_allocated_key = 0;	/* XXX: use macro */
+		bmap->b_ptr_type = NILFS_BMAP_PTR_VS;
+		bmap->b_last_allocated_key = 0;
 		bmap->b_last_allocated_ptr = NILFS_BMAP_INVALID_PTR;
 		break;
 	default:
-		bmap->b_pops = &nilfs_bmap_ptr_ops_v;
-		bmap->b_last_allocated_key = 0;	/* XXX: use macro */
+		bmap->b_ptr_type = NILFS_BMAP_PTR_VM;
+		bmap->b_last_allocated_key = 0;
 		bmap->b_last_allocated_ptr = NILFS_BMAP_INVALID_PTR;
 		break;
 	}
@@ -705,7 +628,7 @@
 	memset(&bmap->b_u, 0, NILFS_BMAP_SIZE);
 	init_rwsem(&bmap->b_sem);
 	bmap->b_inode = &NILFS_BMAP_I(bmap)->vfs_inode;
-	bmap->b_pops = &nilfs_bmap_ptr_ops_gc;
+	bmap->b_ptr_type = NILFS_BMAP_PTR_U;
 	bmap->b_last_allocated_key = 0;
 	bmap->b_last_allocated_ptr = NILFS_BMAP_INVALID_PTR;
 	bmap->b_state = 0;