]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/commitdiff
xfsprogs: Support new AGFL format
authorDave Chinner <dchinner@redhat.com>
Fri, 7 Jun 2013 00:25:28 +0000 (10:25 +1000)
committerBen Myers <bpm@sgi.com>
Tue, 6 Aug 2013 15:56:32 +0000 (10:56 -0500)
With the addition of CRCs to the filesystem format, the AGFL has a
new format structure definition. Existing code that pulls freelist
blocks out via dereferencing agfl->agfl_bno no longer works as the
location of the free list is now variable depending on the disk
format in use.

Hence all the users of agfl_bno need ot be converted to extract the
location of the first free list entry from the AGFL and grab entries
relative to that first entry. It's a simple change, but needs to be
made in several places as there is very little code reuse within and
between the different utilities in xfsprogs.

Signed-off-by: Dave Chinner <dchinner@redhat.com>
Reviewed-by: Ben Myers <bpm@sgi.com>
Signed-off-by: Ben Myers <bpm@sgi.com>
db/check.c
db/freesp.c
repair/phase5.c
repair/scan.c

index 353530bb1422e1e0f512b3a251b10f79060f5809..127e407f3952aab0ab797fe00d5db11bb18e909e 100644 (file)
@@ -3806,6 +3806,7 @@ scan_freelist(
        xfs_agblock_t   bno;
        uint            count;
        int             i;
+       __be32          *freelist;
 
        if (XFS_SB_BLOCK(mp) != XFS_AGFL_BLOCK(mp) &&
            XFS_AGF_BLOCK(mp) != XFS_AGFL_BLOCK(mp) &&
@@ -3835,9 +3836,12 @@ scan_freelist(
                return;
        }
 
+       /* open coded XFS_BUF_TO_AGFL_BNO */
+       freelist = xfs_sb_version_hascrc(&((mp)->m_sb)) ? &agfl->agfl_bno[0]
+                                                       : (__be32 *)agfl;
        count = 0;
        for (;;) {
-               bno = be32_to_cpu(agfl->agfl_bno[i]);
+               bno = be32_to_cpu(freelist[i]);
                set_dbmap(seqno, bno, 1, DBM_FREELIST, seqno,
                        XFS_AGFL_BLOCK(mp));
                count++;
index 472b1f7bc35560c67b53c647450db2c59b5fbd13..228ca07ac06c3afb4bd763436fa888f7d87e004f 100644 (file)
@@ -231,6 +231,7 @@ scan_freelist(
        xfs_agfl_t      *agfl;
        xfs_agblock_t   bno;
        int             i;
+       __be32          *agfl_bno;
 
        if (be32_to_cpu(agf->agf_flcount) == 0)
                return;
@@ -240,6 +241,10 @@ scan_freelist(
        agfl = iocur_top->data;
        i = be32_to_cpu(agf->agf_flfirst);
 
+       /* open coded XFS_BUF_TO_AGFL_BNO */
+       agfl_bno = xfs_sb_version_hascrc(&mp->m_sb) ? &agfl->agfl_bno[0]
+                                                  : (__be32 *)agfl;
+
        /* verify agf values before proceeding */
        if (be32_to_cpu(agf->agf_flfirst) >= XFS_AGFL_SIZE(mp) ||
            be32_to_cpu(agf->agf_fllast) >= XFS_AGFL_SIZE(mp)) {
@@ -250,7 +255,7 @@ scan_freelist(
        }
 
        for (;;) {
-               bno = be32_to_cpu(agfl->agfl_bno[i]);
+               bno = be32_to_cpu(agfl_bno[i]);
                addtohist(seqno, bno, 1);
                if (i == be32_to_cpu(agf->agf_fllast))
                        break;
index 1f71caca5952e8f8a21c165a9298af3de848c830..c7cef4f786fc22e5c460e82a209263855f249d39 100644 (file)
@@ -1208,6 +1208,7 @@ build_agf_agfl(xfs_mount_t        *mp,
        int                     j;
        xfs_agfl_t              *agfl;
        xfs_agf_t               *agf;
+       __be32                  *freelist;
 
        agf_buf = libxfs_getbuf(mp->m_dev,
                        XFS_AG_DADDR(mp, agno, XFS_AGF_DADDR(mp)),
@@ -1277,19 +1278,20 @@ build_agf_agfl(xfs_mount_t      *mp,
                                XFS_AG_DADDR(mp, agno, XFS_AGFL_DADDR(mp)),
                                mp->m_sb.sb_sectsize/BBSIZE);
                agfl = XFS_BUF_TO_AGFL(agfl_buf);
+               freelist = XFS_BUF_TO_AGFL_BNO(mp, agfl_buf);
                memset(agfl, 0, mp->m_sb.sb_sectsize);
                /*
                 * ok, now grab as many blocks as we can
                 */
                i = j = 0;
                while (bno_bt->num_free_blocks > 0 && i < XFS_AGFL_SIZE(mp))  {
-                       agfl->agfl_bno[i] = cpu_to_be32(
+                       freelist[i] = cpu_to_be32(
                                        get_next_blockaddr(agno, 0, bno_bt));
                        i++;
                }
 
                while (bcnt_bt->num_free_blocks > 0 && i < XFS_AGFL_SIZE(mp))  {
-                       agfl->agfl_bno[i] = cpu_to_be32(
+                       freelist[i] = cpu_to_be32(
                                        get_next_blockaddr(agno, 0, bcnt_bt));
                        i++;
                }
index 76bb7f15ea2fa3fa65751fb25e7c5875db9e51db..f79342af476c66e292adc85e9f8c5ee660fbb8a1 100644 (file)
@@ -1041,12 +1041,12 @@ scan_freelist(
        xfs_agf_t       *agf,
        struct aghdr_cnts *agcnts)
 {
-       xfs_agfl_t      *agfl;
        xfs_buf_t       *agflbuf;
        xfs_agnumber_t  agno;
        xfs_agblock_t   bno;
        int             count;
        int             i;
+       __be32          *freelist;
 
        agno = be32_to_cpu(agf->agf_seqno);
 
@@ -1065,7 +1065,7 @@ scan_freelist(
                do_abort(_("can't read agfl block for ag %d\n"), agno);
                return;
        }
-       agfl = XFS_BUF_TO_AGFL(agflbuf);
+       freelist = XFS_BUF_TO_AGFL_BNO(mp, agflbuf);
        i = be32_to_cpu(agf->agf_flfirst);
 
        if (no_modify) {
@@ -1080,7 +1080,7 @@ scan_freelist(
 
        count = 0;
        for (;;) {
-               bno = be32_to_cpu(agfl->agfl_bno[i]);
+               bno = be32_to_cpu(freelist[i]);
                if (verify_agbno(mp, agno, bno))
                        set_bmap(agno, bno, XR_E_FREE);
                else