Long btree pointers are still 64 bit on disk
PATCH 1/1 Long btree pointers are still 64 bit on disk
[XFS] Long btree pointers are still 64 bit on disk
On 32 bit machines with CONFIG_LBD=n, XFS reduces the in memory size of xfs_fsblock_t to 32 bits so that it will fit within 32 bit addressing. However, the disk format for long btree pointers are still 64 bits in size.
The recent btree rewrite failed to take this into account when initialising new btree blocks, setting sibling pointers to NULL and checking if they are NULL. Hence checking whether a 64 bit NULL was the same as a 32 bit NULL was failingi resulting in NULL sibling pointers failing to be detected correctly. This showed up as WANT_CORRUPTED_GOTO shutdowns in xfs_btree_delrec.
Fix this by making all the comparisons and setting of long pointer btree NULL blocks to the disk format, not the in memory format. i.e. use NULLDFSBNO.
--- fs/xfs/xfs_btree.c | 10 +++++----- 1 files changed, 5 insertions(+), 5 deletions(-)
fs/xfs/xfs_btree.c +5 -5
@@ -843,7 +843,7 @@ xfs_btree_ptr_is_null( union xfs_btree_ptr *ptr) {if (cur->bc_flags &XFS_BTREE_LONG_PTRS ) -return be64_to_cpu (ptr->l) ==NULLFSBLOCK ; +return be64_to_cpu (ptr->l) ==NULLDFSBNO ;else return be32_to_cpu (ptr->s) ==NULLAGBLOCK ; }
@@ -854,7 +854,7 @@ xfs_btree_set_ptr_null( union xfs_btree_ptr *ptr) {if (cur->bc_flags &XFS_BTREE_LONG_PTRS ) - ptr->l =cpu_to_be64 (NULLFSBLOCK ); + ptr->l =cpu_to_be64 (NULLDFSBNO );else ptr->s =cpu_to_be32 (NULLAGBLOCK ); }
@@ -918,8 +918,8 @@ xfs_btree_init_block( new->bb_numrecs =cpu_to_be16 (numrecs);if (cur->bc_flags &XFS_BTREE_LONG_PTRS ) { - new->bb_u.l.bb_leftsib =cpu_to_be64 (NULLFSBLOCK ); - new->bb_u.l.bb_rightsib =cpu_to_be64 (NULLFSBLOCK ); + new->bb_u.l.bb_leftsib =cpu_to_be64 (NULLDFSBNO ); + new->bb_u.l.bb_rightsib =cpu_to_be64 (NULLDFSBNO ); }else { new->bb_u.s.bb_leftsib =cpu_to_be32 (NULLAGBLOCK ); new->bb_u.s.bb_rightsib =cpu_to_be32 (NULLAGBLOCK );
@@ -971,7 +971,7 @@ xfs_btree_ptr_to_daddr( union xfs_btree_ptr *ptr) {if (cur->bc_flags &XFS_BTREE_LONG_PTRS ) { -ASSERT (be64_to_cpu (ptr->l) !=NULLFSBLOCK ); +ASSERT (be64_to_cpu (ptr->l) !=NULLDFSBNO );return XFS_FSB_TO_DADDR (cur->bc_mp,be64_to_cpu (ptr->l)); }else {
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
Looks good and passes xfsqs for me.
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
Quoted 1 line · Christoph Hellwig
Looks good and passes xfsqs for me.
Thanks Christoph.
SGI, patch with updated metadata is below. Please include and push to Linus ASAP.
Cheers,
Dave.
-----
[XFS] Long btree pointers are still 64 bit on disk
On 32 bit machines with CONFIG_LBD=n, XFS reduces the in memory size of xfs_fsblock_t to 32 bits so that it will fit within 32 bit addressing. However, the disk format for long btree pointers are still 64 bits in size.
The recent btree rewrite failed to take this into account when initialising new btree blocks, setting sibling pointers to NULL and checking if they are NULL. Hence checking whether a 64 bit NULL was the same as a 32 bit NULL was failingi resulting in NULL sibling pointers failing to be detected correctly. This showed up as WANT_CORRUPTED_GOTO shutdowns in xfs_btree_delrec.
Fix this by making all the comparisons and setting of long pointer btree NULL blocks to the disk format, not the in memory format. i.e. use NULLDFSBNO.
--- fs/xfs/xfs_btree.c | 10 +++++----- 1 files changed, 5 insertions(+), 5 deletions(-)
fs/xfs/xfs_btree.c +5 -5
@@ -843,7 +843,7 @@ xfs_btree_ptr_is_null( union xfs_btree_ptr *ptr) {if (cur->bc_flags &XFS_BTREE_LONG_PTRS ) -return be64_to_cpu (ptr->l) ==NULLFSBLOCK ; +return be64_to_cpu (ptr->l) ==NULLDFSBNO ;else return be32_to_cpu (ptr->s) ==NULLAGBLOCK ; }
@@ -854,7 +854,7 @@ xfs_btree_set_ptr_null( union xfs_btree_ptr *ptr) {if (cur->bc_flags &XFS_BTREE_LONG_PTRS ) - ptr->l =cpu_to_be64 (NULLFSBLOCK ); + ptr->l =cpu_to_be64 (NULLDFSBNO );else ptr->s =cpu_to_be32 (NULLAGBLOCK ); }
@@ -918,8 +918,8 @@ xfs_btree_init_block( new->bb_numrecs =cpu_to_be16 (numrecs);if (cur->bc_flags &XFS_BTREE_LONG_PTRS ) { - new->bb_u.l.bb_leftsib =cpu_to_be64 (NULLFSBLOCK ); - new->bb_u.l.bb_rightsib =cpu_to_be64 (NULLFSBLOCK ); + new->bb_u.l.bb_leftsib =cpu_to_be64 (NULLDFSBNO ); + new->bb_u.l.bb_rightsib =cpu_to_be64 (NULLDFSBNO ); }else { new->bb_u.s.bb_leftsib =cpu_to_be32 (NULLAGBLOCK ); new->bb_u.s.bb_rightsib =cpu_to_be32 (NULLAGBLOCK );
@@ -971,7 +971,7 @@ xfs_btree_ptr_to_daddr( union xfs_btree_ptr *ptr) {if (cur->bc_flags &XFS_BTREE_LONG_PTRS ) { -ASSERT (be64_to_cpu (ptr->l) !=NULLFSBLOCK ); +ASSERT (be64_to_cpu (ptr->l) !=NULLDFSBNO );return XFS_FSB_TO_DADDR (cur->bc_mp,be64_to_cpu (ptr->l)); }else {
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
Quoted 6 lines · Dave Chinner
Quoted 1 line · Christoph Hellwig
Looks good and passes xfsqs for me.
Thanks Christoph.
SGI, patch with updated metadata is below.
I've added those tags myself as well, hope it's ok if tags order is different. It's already in ready to push state.
Quoted 2 lines
Please include and push
to Linus ASAP.
The account breakage on oss hold my push. Seems Russell resolved it, will push right away.
Felix
Quoted 80 lines
Cheers,
Dave.
-----
[XFS] Long btree pointers are still 64 bit on disk
On 32 bit machines with
CONFIG_LBD=n, XFS reduces the in memory size ofxfs_fsblock_tto 32 bits so that it will fit within 32 bit addressing. However, the disk format for long btree pointers are still 64 bits in size.The recent btree rewrite failed to take this into account when initialising new btree blocks, setting sibling pointers to NULL and checking if they are NULL. Hence checking whether a 64 bit NULL was the same as a 32 bit NULL was failingi resulting in NULL sibling pointers failing to be detected correctly. This showed up as
WANT_CORRUPTED_GOTOshutdowns inxfs_btree_delrec.Fix this by making all the comparisons and setting of long pointer btree NULL blocks to the disk format, not the in memory format. i.e. use NULLDFSBNO.
Reported-by Alexander Beregalov <[email protected]>Reported-by Jacek Luczak <[email protected]>Reported-by Danny ter Haar <[email protected]>Signed-off-by Dave Chinner <[email protected]>Tested-by Jacek Luczak <[email protected]>Reviewed-by Christoph Hellwig <[email protected]>--- fs/xfs/xfs_btree.c | 10 +++++----- 1 files changed, 5 insertions(+), 5 deletions(-)fs/xfs/xfs_btree.c +5
-5@@ -843,7 +843,7 @@ xfs_btree_ptr_is_null( union xfs_btree_ptr *ptr) {if (cur->bc_flags &XFS_BTREE_LONG_PTRS ) -return be64_to_cpu (ptr->l) ==NULLFSBLOCK ; +return be64_to_cpu (ptr->l) ==NULLDFSBNO ;else return be32_to_cpu (ptr->s) ==NULLAGBLOCK ; }@@ -854,7 +854,7 @@ xfs_btree_set_ptr_null( union xfs_btree_ptr *ptr) {if (cur->bc_flags &XFS_BTREE_LONG_PTRS ) - ptr->l =cpu_to_be64 (NULLFSBLOCK ); + ptr->l =cpu_to_be64 (NULLDFSBNO );else ptr->s =cpu_to_be32 (NULLAGBLOCK ); }@@ -918,8 +918,8 @@ xfs_btree_init_block( new->bb_numrecs =cpu_to_be16 (numrecs);if (cur->bc_flags &XFS_BTREE_LONG_PTRS ) { - new->bb_u.l.bb_leftsib =cpu_to_be64 (NULLFSBLOCK ); - new->bb_u.l.bb_rightsib =cpu_to_be64 (NULLFSBLOCK ); + new->bb_u.l.bb_leftsib =cpu_to_be64 (NULLDFSBNO ); + new->bb_u.l.bb_rightsib =cpu_to_be64 (NULLDFSBNO ); }else { new->bb_u.s.bb_leftsib =cpu_to_be32 (NULLAGBLOCK ); new->bb_u.s.bb_rightsib =cpu_to_be32 (NULLAGBLOCK );@@ -971,7 +971,7 @@ xfs_btree_ptr_to_daddr( union xfs_btree_ptr *ptr) {if (cur->bc_flags &XFS_BTREE_LONG_PTRS ) { -ASSERT (be64_to_cpu (ptr->l) !=NULLFSBLOCK ); +ASSERT (be64_to_cpu (ptr->l) !=NULLDFSBNO );return XFS_FSB_TO_DADDR (cur->bc_mp,be64_to_cpu (ptr->l)); }else {
Quoted 4 lines
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs