Skip to contentSkip to conversation

move xfs_bmbt_newroot to common code

PATCH In review Christoph Hellwig 2 participants 2 messages Aug 4, 2008 – Aug 5, 2008 XFS filesystem

lore
Share & tools
lore
#0 lore raw

PATCH 20/26 move xfs_bmbt_newroot to common code

xfs_bmbt_newroot is a mostly generic implementation of moving from an inode root to a real block based root. So move it to xfs_btree.c where it can use all the nice infrastructure there and make it pointer size agnostic

The new name for it is xfs_btree_iroot_to_root which is not very nice but at least slightly more descriptive than the old name.

fs/xfs/xfs_btree.c +100 -0
Index: linux-2.6-xfs/fs/xfs/xfs_btree.c
===================================================================
@@ -2250,6 +2250,106 @@ error0:
 }
 
 /*
+ * Give the btree a real root block.  Copy the old broot contents
+ * down into a real block and make the broot point to it.
+ */
+int						/* error */
+xfs_btree_iroot_to_root(
+	struct xfs_btree_cur	*cur,		/* btree cursor */
+	int			*logflags,	/* logging flags for inode */
+	int			*stat)		/* return status - 0 fail */
+{
+	struct xfs_buf		*bp;		/* buffer for block */
+	struct xfs_buf		*cbp;		/* buffer for cblock */
+	struct xfs_btree_block	*block;		/* btree block */
+	struct xfs_btree_block	*cblock;	/* child btree block */
+	union xfs_btree_key	*ckp;		/* child key pointer */
+	union xfs_btree_ptr	*cpp;		/* child ptr pointer */
+	union xfs_btree_key	*kp;		/* pointer to btree key */
+	union xfs_btree_ptr	*pp;		/* pointer to block addr */
+	union xfs_btree_ptr	nptr;		/* new block addr */
+	int			level;		/* btree level */
+	int			error;		/* error return code */
+#ifdef DEBUG
+	int			i;		/* loop counter */
+#endif
+
+	XFS_BTREE_TRACE_CURSOR(cur, XBT_ENTRY);
+	XFS_BTREE_STATS_INC(cur, newroot);
+
+	level = cur->bc_nlevels - 1;
+	/* XXX(hch): this should be an get_inode_from_root, right? */
+	block = xfs_btree_get_block(cur, level, &bp);
+	pp = cur->bc_ops->ptr_addr(cur, 1, block);
+
+	/* Allocate the new block. If we can't do it, we're toast. Give up. */
+	error = cur->bc_ops->alloc_block(cur, pp, &nptr, 1, stat);
+	if (error)
+		goto error0;
+	if (*stat == 0) {
+		XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT);
+		return 0;
+	}
+	XFS_BTREE_STATS_INC(cur, alloc);
+
+	/* Copy the root into a real block. */
+	error = xfs_btree_get_buf_block(cur, &nptr, 0, &cblock, &cbp);
+	if (error)
+		goto error0;
+
+	if (cur->bc_flags & XFS_BTREE_LONG_PTRS)
+		memcpy(cblock, block, sizeof(struct xfs_btree_lblock));
+	else
+		memcpy(cblock, block, sizeof(struct xfs_btree_sblock));
+
+	be16_add(&block->bb_level, 1);
+	xfs_btree_set_numrecs(block, 1);
+	cur->bc_nlevels++;
+	cur->bc_ptrs[level + 1] = 1;
+
+	kp = cur->bc_ops->key_addr(cur, 1, block);
+	ckp = cur->bc_ops->key_addr(cur, 1, cblock);
+	cur->bc_ops->copy_keys(cur, kp, ckp, xfs_btree_get_numrecs(cblock));
+
+	cpp = cur->bc_ops->ptr_addr(cur, 1, cblock);
+#ifdef DEBUG
+	for (i = 0; i < be16_to_cpu(cblock->bb_numrecs); i++) {
+		error = xfs_btree_check_ptr(cur, pp, i, level);
+		if (error)
+			goto error0;
+	}
+#endif
+	xfs_btree_copy_ptrs(cur, pp, cpp, xfs_btree_get_numrecs(cblock));
+
+#ifdef DEBUG
+	error = xfs_btree_check_ptr(cur, &nptr, 0, level);
+	if (error)
+		goto error0;
+#endif
+	xfs_btree_set_ptr(cur, pp, 0, &nptr);
+
+	cur->bc_ops->realloc_root(cur, 1 - xfs_btree_get_numrecs(cblock));
+	xfs_btree_setbuf(cur, level, cbp);
+
+	/*
+	 * Do all this logging at the end so that
+	 * the root is at the right level.
+	 */
+	xfs_btree_log_block(cur, cbp, XFS_BB_ALL_BITS);
+	cur->bc_ops->log_keys(cur, cbp, 1, be16_to_cpu(cblock->bb_numrecs));
+	xfs_btree_log_ptrs(cur, cbp, 1, be16_to_cpu(cblock->bb_numrecs));
+
+	*logflags |=
+		XFS_ILOG_CORE | XFS_ILOG_FBROOT(cur->bc_private.b.whichfork);
+	*stat = 1;
+	XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT);
+	return 0;
+error0:
+	XFS_BTREE_TRACE_CURSOR(cur, XBT_ERROR);
+	return error;
+}
+
+/*
  * Allocate a new root block, fill it in.
  */
 int				/* error */
fs/xfs/xfs_bmap.c +1 -1
Index: linux-2.6-xfs/fs/xfs/xfs_bmap.c
===================================================================
@@ -476,7 +476,7 @@ xfs_bmap_add_attrfork_btree(
 			goto error0;
 		/* must be at least one entry */
 		XFS_WANT_CORRUPTED_GOTO(stat == 1, error0);
-		if ((error = xfs_bmbt_newroot(cur, flags, &stat)))
+		if ((error = xfs_btree_iroot_to_root(cur, flags, &stat)))
 			goto error0;
 		if (stat == 0) {
 			xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR);
fs/xfs/xfs_bmap_btree.c +11 -112

147 lines not on this page · raw message

fs/xfs/xfs_bmap_btree.h +0 -6
Index: linux-2.6-xfs/fs/xfs/xfs_bmap_btree.h
===================================================================
@@ -255,12 +255,6 @@ extern void xfs_bmbt_log_block(struct xf
 extern void xfs_bmbt_log_recs(struct xfs_btree_cur *, struct xfs_buf *, int,
 				int);
 
-/*
- * Give the bmap btree a new root block.  Copy the old broot contents
- * down into a real block and make the broot point to it.
- */
-extern int xfs_bmbt_newroot(struct xfs_btree_cur *cur, int *lflags, int *stat);
-
 extern void xfs_bmbt_set_all(xfs_bmbt_rec_host_t *r, xfs_bmbt_irec_t *s);
 extern void xfs_bmbt_set_allf(xfs_bmbt_rec_host_t *r, xfs_fileoff_t o,
 			xfs_fsblock_t b, xfs_filblks_t c, xfs_exntst_t v);
fs/xfs/xfs_btree.h +3 -1
Index: linux-2.6-xfs/fs/xfs/xfs_btree.h
===================================================================
@@ -183,8 +183,9 @@ struct xfs_btree_ops {
 	/* cursor operations */
 	struct xfs_btree_cur *(*dup_cursor)(struct xfs_btree_cur *);
 
-	/* get inode rooted btree root */
+	/* btree root in inode support */
 	struct xfs_btree_block *(*get_root_from_inode)(struct xfs_btree_cur *);
+	void	(*realloc_root)(struct xfs_btree_cur *cur, int index);
 
 	/* btree root operations */
 	void	(*set_root)(struct xfs_btree_cur *cur,
@@ -586,6 +587,7 @@ int xfs_btree_rshift(struct xfs_btree_cu
 int xfs_btree_split(struct xfs_btree_cur *, int, union xfs_btree_ptr *,
 		union xfs_btree_key *, struct xfs_btree_cur **, int *);
 int xfs_btree_new_root(struct xfs_btree_cur *, int *);
+int xfs_btree_iroot_to_root(struct xfs_btree_cur *, int *, int *);
 
 
 /*
#1 lore raw
Quoted 7 lines · Christoph Hellwig

xfs_bmbt_newroot is a mostly generic implementation of moving from an inode root to a real block based root. So move it to xfs_btree.c where it can use all the nice infrastructure there and make it pointer size agnostic

The new name for it is xfs_btree_iroot_to_root which is not very nice but at least slightly more descriptive than the old name.

.....

fs/xfs/xfs_btree.c error0: · line 2282

Quoted 7 lines
fs/xfs/xfs_btree.c +7 -0
+
+	XFS_BTREE_TRACE_CURSOR(cur, XBT_ENTRY);
+	XFS_BTREE_STATS_INC(cur, newroot);
+
+	level = cur->bc_nlevels - 1;
+	/* XXX(hch): this should be an get_inode_from_root, right? */
+	block = xfs_btree_get_block(cur, level, &bp);

Yes, probably should be. Also an assert to ensure the btree does have the root in inode falg set might be appropriate....

Otherwise looks fine.

Cheers,

Dave.

Signature · 2 lines
Dave Chinner
[email protected]