]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/commitdiff
repair: access helpers for on-disk inobt record freecount
authorBrian Foster <bfoster@redhat.com>
Fri, 31 Jul 2015 01:03:51 +0000 (11:03 +1000)
committerDave Chinner <david@fromorbit.com>
Fri, 31 Jul 2015 01:03:51 +0000 (11:03 +1000)
The on-disk inobt record has two formats depending on whether sparse
inode support is enabled or not. If so, the freecount field is a single
byte and does not require byte-conversion. Otherwise, it is a 4-byte
field and does.

Create the inorec_[get|set]_freecount() helpers to abstract this detail
away from the core repair code.

Signed-off-by: Brian Foster <bfoster@redhat.com>
Reviewed-by: Dave Chinner <dchinner@redhat.com>
Signed-off-by: Dave Chinner <david@fromorbit.com>
repair/incore.h
repair/phase5.c
repair/scan.c

index 5a63e1e16a14ae4b571639e83b45227660de8f80..c92475eafebbd38a8dedfe61ae3777d7cab8d0e4 100644 (file)
@@ -591,4 +591,32 @@ typedef struct bm_cursor  {
 
 void init_bm_cursor(bmap_cursor_t *cursor, int num_level);
 
+/*
+ * On-disk inobt record helpers. The sparse inode record format has a single
+ * byte freecount. The older format has a 32-bit freecount and thus byte
+ * conversion is necessary.
+ */
+
+static inline int
+inorec_get_freecount(
+       struct xfs_mount        *mp,
+       struct xfs_inobt_rec    *rp)
+{
+       if (xfs_sb_version_hassparseinodes(&mp->m_sb))
+               return rp->ir_u.sp.ir_freecount;
+       return be32_to_cpu(rp->ir_u.f.ir_freecount);
+}
+
+static inline void
+inorec_set_freecount(
+       struct xfs_mount        *mp,
+       struct xfs_inobt_rec    *rp,
+       int                     freecount)
+{
+       if (xfs_sb_version_hassparseinodes(&mp->m_sb))
+               rp->ir_u.sp.ir_freecount = freecount;
+       else
+               rp->ir_u.f.ir_freecount = cpu_to_be32(freecount);
+}
+
 #endif /* XFS_REPAIR_INCORE_H */
index 0601810a81aaeb48bd14c46cce477cc45c215333..7372734c1c151caa71561142fcd3d131094891c8 100644 (file)
@@ -1258,11 +1258,14 @@ build_ino_tree(xfs_mount_t *mp, xfs_agnumber_t agno,
                                inocnt++;
                        }
 
-                       if (!xfs_sb_version_hassparseinodes(&mp->m_sb)) {
-                               bt_rec[j].ir_u.f.ir_freecount =
-                                                       cpu_to_be32(finocnt);
+                       /*
+                        * Set the freecount and check whether we need to update
+                        * the sparse format fields. Otherwise, skip to the next
+                        * record.
+                        */
+                       inorec_set_freecount(mp, &bt_rec[j], finocnt);
+                       if (!xfs_sb_version_hassparseinodes(&mp->m_sb))
                                goto nextrec;
-                       }
 
                        /*
                         * Convert the 64-bit in-core sparse inode state to the
@@ -1280,7 +1283,6 @@ build_ino_tree(xfs_mount_t *mp, xfs_agnumber_t agno,
                                sparse >>= XFS_INODES_PER_HOLEMASK_BIT;
                        }
 
-                       bt_rec[j].ir_u.sp.ir_freecount = finocnt;
                        bt_rec[j].ir_u.sp.ir_count = inocnt;
                        bt_rec[j].ir_u.sp.ir_holemask = cpu_to_be16(holemask);
 
index e3895c2035c758bdfc788033b317bd0185d00810..1a6f0c5430363bf447859b4f2e97446a7ee97d1b 100644 (file)
@@ -786,10 +786,7 @@ scan_single_ino_chunk(
        off = XFS_AGINO_TO_OFFSET(mp, ino);
        agbno = XFS_AGINO_TO_AGBNO(mp, ino);
        lino = XFS_AGINO_TO_INO(mp, agno, ino);
-       if (xfs_sb_version_hassparseinodes(&mp->m_sb))
-               freecount = rp->ir_u.sp.ir_freecount;
-       else
-               freecount = be32_to_cpu(rp->ir_u.f.ir_freecount);
+       freecount = inorec_get_freecount(mp, rp);
 
        /*
         * on multi-block block chunks, all chunks start
@@ -987,10 +984,7 @@ scan_single_finobt_chunk(
        off = XFS_AGINO_TO_OFFSET(mp, ino);
        agbno = XFS_AGINO_TO_AGBNO(mp, ino);
        lino = XFS_AGINO_TO_INO(mp, agno, ino);
-       if (xfs_sb_version_hassparseinodes(&mp->m_sb))
-               freecount = rp->ir_u.sp.ir_freecount;
-       else
-               freecount = be32_to_cpu(rp->ir_u.f.ir_freecount);
+       freecount = inorec_get_freecount(mp, rp);
 
        /*
         * on multi-block block chunks, all chunks start at the beginning of the
@@ -1331,10 +1325,7 @@ _("inode btree block claimed (state %d), agno %d, bno %d, suspect %d\n"),
                 * the block.  skip processing of bogus records.
                 */
                for (i = 0; i < numrecs; i++) {
-                       if (xfs_sb_version_hassparseinodes(&mp->m_sb))
-                               freecount = rp[i].ir_u.sp.ir_freecount;
-                       else
-                               freecount = be32_to_cpu(rp[i].ir_u.f.ir_freecount);
+                       freecount = inorec_get_freecount(mp, &rp[i]);
 
                        if (magic == XFS_IBT_MAGIC ||
                            magic == XFS_IBT_CRC_MAGIC) {