Red Hat Bugzilla – Bug 1518938
gfs2_edit: indirect pointers print the wrong offset
Last modified: 2018-04-10 04:43:30 EDT
Description of problem: When you dump a gfs2 dinode with gfs2_edit it prints all the block pointers in a tree. It's supposed to print the offsets of those pointers as well. That works okay for non-sparse files, but for sparse files, the offsets are incorrect. I think it's printing a pointer counter rather than the pointer number. This can be very confusing when trying to debug customer metadata. Version-Release number of selected component (if applicable): All How reproducible: Every time Steps to Reproduce: 1.mkfs.gfs2 -p lock_nolock -O -j1 /dev/fsck/bob|grep Resource 2.mount -tgfs2 /dev/fsck/bob /mnt/gfs2 3.dd if=/dev/zero of=/mnt/gfs2/filler-P bs=1 count=1 seek=1P 4.umount /mnt/gfs2 5.gfs2_edit -p root /dev/fsck/bob|grep filler 6.gfs2_edit -p <resulting dinode block> /dev/fsck/bob Actual results: Block #33136 (0x8170) of 26214400 (0x1900000) (disk inode) Dinode: mh_magic 0x01161970(hex) mh_type 4 0x4 mh_format 400 0x190 no_formal_ino 1 0x1 no_addr 33136 0x8170 di_mode 0100644(decimal) di_uid 0 0x0 di_gid 0 0x0 di_nlink 1 0x1 di_size 1125899906842625 0x4000000000001 di_blocks 10 0xa di_atime 1511982636 0x5a1f062c di_mtime 1511982636 0x5a1f062c di_ctime 1511982636 0x5a1f062c di_major 0 0x0 di_minor 0 0x0 di_goal_meta 33145 0x8179 di_goal_data 33145 0x8179 di_flags 0x00000000(hex) di_payload_format 0 0x0 di_height 5 0x5 di_depth 0 0x0 di_entries 0 0x0 di_eattr 0 0x0 This inode contains 2 indirect blocks (at height 0 of 5) Indirect blocks: 0 => 0x8171 / 33137 (data offset 0x0 / 0 / 0.00K) 0 => 0x8172 / 33138 (data offset 0x0 / 0 / 0.00K) 0 => 0x8173 / 33139 (data offset 0x0 / 0 / 0.00K) 0 => 0x8174 / 33140 (data offset 0x0 / 0 / 0.00K) 1 => 0x8175 / 33141 (data offset 0x3e835ca144000 / 1099742651367424 / 1000.21T) 0 => 0x8176 / 33142 (data offset 0x3e835ca144000 / 1099742651367424 / 1000.21T) 0 => 0x8177 / 33143 (data offset 0x3e835ca144000 / 1099742651367424 / 1000.21T) 0 => 0x8178 / 33144 (data offset 0x3e835ca144000 / 1099742651367424 / 1000.21T) 0 => 0x8179 / 33145 (data offset 0x3e835ca144000 / 1099742651367424 / 1000.21T) If you look at the actual pointers in gfs2_edit interactive mode, you'll see that they're not at offsets 1 or 0, but farther down the metapath. Expected results: The last 5 lines of indirect pointers say "1 =>" and "0 =>" which is the pointer count, not the offset of the pointer. It's supposed to read: 4 => 0x8175 / 33141 (data offset 0x3e835ca144000 / 1099742651367424 / 1000.21T) 0x30 => 0x8176 / 33142 (data offset 0x3e835ca144000 / 1099742651367424 / 1000.21T) 0xd8 => 0x8177 / 33143 (data offset 0x3e835ca144000 / 1099742651367424 / 1000.21T) 0x1b0 => 0x8178 / 33144 (data offset 0x3e835ca144000 / 1099742651367424 / 1000.21T) 0x144 => 0x8179 / 33145 (data offset 0x3e835ca144000 / 1099742651367424 / 1000.21T) -or- if you don't like hex: 4 => 0x8175 / 33141 (data offset 0x3e835ca144000 / 1099742651367424 / 1000.21T) 48 => 0x8176 / 33142 (data offset 0x3e835ca144000 / 1099742651367424 / 1000.21T) 216 => 0x8177 / 33143 (data offset 0x3e835ca144000 / 1099742651367424 / 1000.21T) 432 => 0x8178 / 33144 (data offset 0x3e835ca144000 / 1099742651367424 / 1000.21T) 324 => 0x8179 / 33145 (data offset 0x3e835ca144000 / 1099742651367424 / 1000.21T) Additional info: This ought to be a very easy thing to fix: Just use the offset within the (block - sizeof(struct gfs2_dinode)) / 8. Or, rather than skipping any zero-pointers, make it keep count. I should have done this many years ago.
Patch has been pushed upstream: https://pagure.io/gfs2-utils/c/1a093d1233a4d5ef83d6141928f5de693f1333ee
Verified in gfs2-utils-3.1.10-6.el7: [root@host-002 ~]# rpm -q gfs2-utils gfs2-utils-3.1.10-6.el7.x86_64 [root@host-002 ~]# mkfs.gfs2 -p lock_nolock -O -j1 /dev/mapper/testvg1-testlv1 |grep Resource Resource groups: 9 [root@host-002 ~]# mount -tgfs2 /dev/mapper/testvg1-testlv1 /mnt/gfs2/ [root@host-002 ~]# dd if=/dev/zero of=/mnt/gfs2/filler-P bs=1 count=1 seek=1P 1+0 records in 1+0 records out 1 byte (1 B) copied, 0.000742194 s, 1.3 kB/s [root@host-002 ~]# umount /mnt/gfs2 [root@host-002 ~]# gfs2_edit -p root /dev/mapper/testvg1-testlv1 |grep filler 3/3 [5eb09a1a] 1/33125 (0x1/0x8165) +1: File filler-P [root@host-002 ~]# gfs2_edit -p 0x8165 /dev/mapper/testvg1-testlv1 Block #33125 (0x8165) of 522240 (0x7f800) (disk inode) Dinode: mh_magic 0x01161970(hex) mh_type 4 0x4 mh_format 400 0x190 no_formal_ino 1 0x1 no_addr 33125 0x8165 di_mode 0100644(decimal) di_uid 0 0x0 di_gid 0 0x0 di_nlink 1 0x1 di_size 1125899906842625 0x4000000000001 di_blocks 11 0xb di_atime 1516226508 0x5a5fc7cc di_mtime 1516226508 0x5a5fc7cc di_ctime 1516226508 0x5a5fc7cc di_major 0 0x0 di_minor 0 0x0 di_goal_meta 33135 0x816f di_goal_data 33135 0x816f di_flags 0x00000000(hex) di_payload_format 0 0x0 di_height 5 0x5 di_depth 0 0x0 di_entries 0 0x0 di_eattr 33126 0x8166 This inode contains 2 indirect blocks (at height 0 of 5) Indirect blocks: 0: 0x0 => 0x8167 / 33127 (data offset 0x0 / 0 / 0.00K) 0: 0x0 => 0x8168 / 33128 (data offset 0x0 / 0 / 0.00K) 0: 0x0 => 0x8169 / 33129 (data offset 0x0 / 0 / 0.00K) 0: 0x0 => 0x816a / 33130 (data offset 0x0 / 0 / 0.00K) 1: 0x4 => 0x816b / 33131 (data offset 0x3e835ca144000 / 1099742651367424 / 1000.21T) 0: 0x30 => 0x816c / 33132 (data offset 0x3e835ca144000 / 1099742651367424 / 1000.21T) 0: 0xd8 => 0x816d / 33133 (data offset 0x3e835ca144000 / 1099742651367424 / 1000.21T) 0: 0x1b0 => 0x816e / 33134 (data offset 0x3e835ca144000 / 1099742651367424 / 1000.21T) 0: 0x144 => 0x816f / 33135 (data offset 0x3e835ca144000 / 1099742651367424 / 1000.21T)
Since the problem described in this bug report should be resolved in a recent advisory, it has been closed with a resolution of ERRATA. For information on the advisory, and where to find the updated files, follow the link below. If the solution does not work for you, open a new bug report. https://access.redhat.com/errata/RHBA-2018:0668